我有一個字串向量的向量。我想找到每列中最長字串的長度。所有的子向量都具有相同的長度并存盤了一個元素,因此使用兩個 for 回圈和反向索引很容易找到它。
vector<vector<string>> myvec = {
{ "a", "aaa", "aa"},
{"bb", "b", "bbbb"},
{"cc", "cc", "ccc"}
};
但是是否可以在不使用索引的情況下使用迭代器來做到這一點?
uj5u.com熱心網友回復:
假設內部向量的長度都相同,你可以有類似的東西
template <typename T>
class columnwise {
std::vector<std::vector<T>> * underlying;
struct proxy {
std::vector<std::vector<T>> * underlying;
std::vector<T>::difference_type offset;
struct iterator {
std::vector<std::vector<T>>::iterator outer;
std::vector<T>::difference_type offset;
using reference = typename std::vector<T>::reference;
using pointer = typename std::vector<T>::pointer;
iterator operator () { outer; return *this; }
reference operator*() { return *(outer->begin() offset); }
pointer operator->() { return (outer->begin() offset).operator->(); }
bool operator==(iterator rhs) { return (outer == rhs.outer) && (offset == rhs.offset); }
};
public:
iterator begin() { return { underlying->begin(), offset }; }
iterator end() { return { underlying->end(), offset }; }
};
struct iterator {
// member type aliases
std::vector<std::vector<T>> * underlying;
std::vector<T>::difference_type offset;
iterator operator () { offset; return *this; }
proxy operator*() { return { underlying, offset }; }
bool operator==(iterator rhs) { return (underlying== rhs.underlying) && (offset == rhs.offset); }
};
std::vector<T>::difference_type inner_size() { if (auto it = underlying->begin(); it != underlying->end()) { return it->size(); } return 0; }
public:
columnwise(std::vector<std::vector<T>> & vec) : underlying(&vec) {}
iterator begin() { return { underlying, 0 }; }
iterator end() { return { underlying, inner_size() }; }
};
哪個迭代如你所料。
uj5u.com熱心網友回復:
這樣的事情呢?
std::vector<std::size_t> max_lengths(myvec.front().size(), 0);
for (auto const& strings : myvec) {
std::transform(max_lengths.begin(), max_lengths.end(), strings.begin(), max_lengths.begin(),
[](std::size_t l, std::string const& s) {
return std::max(l, s.size());
}
);
}
演示
uj5u.com熱心網友回復:
這是使用類似于 Nelfeals 答案的 C 20 范圍的解決方案:
// returns a function returning the i-th element of an iterable container
auto ith_element = [](size_t i) {
return [i](auto const& v){
return v[i];
};
};
// returns the size of something
auto length = [](auto const& s){ return s.size(); };
// returns the max length of the i_th column
auto max_length_per_col = [&](auto const& v, size_t i) {
return std::ranges::max(
v | std::views::transform(ith_element(i)) // range containing only the ith element of each element of the input range
| std::views::transform(length) // range containing the length of each element of the input range
);
};
我個人喜歡范圍庫如何幫助您通過代碼傳達意圖,而不必規定實作目標的程序。
請注意,如果您將內部 lambda 的主體替換為ith_element以下塊,它也適用于沒有隨機訪問的可迭代容器。
auto it = v.cbegin();
std::ranges::advance(it, i);
return *it
演示
最后一點,此解決方案允許您在給定列索引的情況下迭代一列。我建議不要為以下實作列迭代器:迭代器的存在意味著記憶體中存在可以迭代的東西。列的存在僅由您提供給我們的附加資訊暗示,即所有行的長度相同。如果您確實需要列和行的迭代器,我會將您的容器包裝在一種新型別中,該型別可以正確傳達該意圖并為該新型別實作迭代器。vector<vector>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/522174.html
標籤:C 矩阵向量迭代器
