![](/img/trans.png)
[英]std::map with iterators to std::list from iterators of std::map
[英]Zip several std::list iterators together
使用 boost 库,可以使用zip iterator将已知数量的迭代器压缩在一起,但是当要压缩的迭代器数量直到运行时才知道时怎么办?
为了稍微扩展一下,我有一个大小相同的列表列表,我需要将每个索引处的所有值组合在一起,并将它们提供给另一个操作。 现在这都是手动的,我觉得应该有更好的方法。
示例:
假设我有 3 个列表:
我需要将这些列表转换为:
直到运行时,我才知道输入中有多少个列表。
好吧,在花了将近 1/2 小时之后,我想出了这个可以进一步改进的dynamic_zip_iterator
类,使它看起来像 STL 类迭代器。 到目前为止,它非常具体,因为我在其中硬编码了std::list
,您可以将其替换为std::vector
或者可以使其更通用:
无论如何,看看它:
template<typename T>
struct dynamic_zip_iterator
{
typedef typename std::list<T>::iterator list_iterator;
std::list<list_iterator> iterators;
std::list<std::list<T>> * plists;
dynamic_zip_iterator(std::list<std::list<T>> & lists, bool isbegin) : plists(&lists)
{
auto it = plists->begin();
for( ; it != plists->end(); ++it)
{
if ( isbegin )
iterators.push_back(it->begin());
else
iterators.push_back(it->end());
}
}
dynamic_zip_iterator(const dynamic_zip_iterator & zip) :
plists(zip.plists),iterators(zip.iterators) {}
dynamic_zip_iterator operator++()
{
auto it = iterators.begin();
for( ; it != iterators.end(); ++it)
++(*it);
return *this;
}
std::list<T> operator*()
{
std::list<T> lst;
auto it = iterators.begin();
for( ; it != iterators.end(); ++it)
lst.push_back(*(*it));
return lst;
}
bool operator!=(dynamic_zip_iterator &zip)
{
auto it1 = iterators.begin();
auto it2 = zip.iterators.begin();
return (*it1) != (*it2);
}
static dynamic_zip_iterator begin(std::list<std::list<T>> & lists)
{
return dynamic_zip_iterator<T>(lists, true);
}
static dynamic_zip_iterator end(std::list<std::list<T>> & lists)
{
return dynamic_zip_iterator<T>(lists, false);
}
};
使用它你的问题减少到这个功能:
std::list<std::list<int>> create_lists(std::list<std::list<int>>& lists)
{
std::list<std::list<int>> results;
auto begin = dynamic_zip_iterator<int>::begin(lists);
auto end = dynamic_zip_iterator<int>::end(lists);
for( ; begin != end ; ++begin)
{
results.push_back(*begin);
}
return results;
}
测试代码:
int main() {
int a[] = {1, 2, 3, 4, 5}, b[] = {11, 12, 13, 14, 15}, c[] = {21, 22, 23, 24, 25};
std::list<int> l1(a,a+5), l2(b,b+5), l3(c,c+5);
std::list<std::list<int>> lists;
lists.push_back(l1);
lists.push_back(l2);
lists.push_back(l3);
std::list<std::list<int>> newlists = create_lists(lists);
for(auto lst = newlists.begin(); lst != newlists.end(); ++lst)
{
std::cout << "[";
std::copy(lst->begin(), lst->end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "]" << std::endl;
}
return 0;
}
输出:
[1 11 21 ]
[2 12 22 ]
[3 13 23 ]
[4 14 24 ]
[5 15 25 ]
在线演示: http : //ideone.com/3FJu1
我很确定今天没有任何东西存在。 但是为什么不创建一个非常简单的迭代器元素列表呢? 那会奏效的,我敢肯定!
为for
语句的所有 3 个部分创建一个函数 --> begin, end, increment
这应该足够了! 下面详细介绍一下。
begin : (const ref to list of list, reference to empty list of iterators) --> 使用 begin() 为每个子列表构造迭代器列表
end : (const ref to list of iterators, const ref to list of lists) --> 如果一个迭代器在其列表的末尾,则为真
increment : (ref to list of iterators) --> 增加列表中的每个迭代器
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.