【发布时间】:2018-03-16 01:11:12
【问题描述】:
我正在解决一个问题,该问题需要遍历 K 向量的所有元素组合,一次取一个。例如,对于K=2 向量v1 = [0 1] 和v2 = [3 4],我将遍历(0,3), (0,4), (1,3), (1,4)。
由于K 是在运行时确定的,因此我不能使用显式 for 循环。我目前的方法是基于this solution,它实现了一个“里程表”,为每个向量增加一个索引。
#include <vector>
#include <iostream>
int main(int argc, char * argv[])
{
std::vector<int> v1( {1, 2, 3} );
std::vector<int> v2( {-2, 5} );
std::vector<int> v3( {0, 1, 2} );
std::vector<std::vector<int> > vv( {v1, v2 ,v3} );
// Iterate combinations of elems in v1, v2, v3, one at a time
std::vector<std::vector<int>::iterator> vit;
for (auto& v : vv)
vit.push_back(v.begin());
int K = vv.size();
while (vit[0] != vv[0].end())
{
std::cout << "Processing combination: [";
for (auto& i : vit)
std::cout << *i << " ";
std::cout << "]\n";
// increment "odometer" by 1
++vit[K-1];
for (int i = K-1; (i > 0) && (vit[i] == vv[i].end()); --i)
{
vit[i] = vv[i].begin();
++vit[i-1];
}
}
return 0;
}
输出:
Processing combination: [1 -2 0 ]
Processing combination: [1 -2 1 ]
Processing combination: [1 -2 2 ]
Processing combination: [1 5 0 ]
Processing combination: [1 5 1 ]
Processing combination: [1 5 2 ]
Processing combination: [2 -2 0 ]
Processing combination: [2 -2 1 ]
Processing combination: [2 -2 2 ]
Processing combination: [2 5 0 ]
Processing combination: [2 5 1 ]
Processing combination: [2 5 2 ]
Processing combination: [3 -2 0 ]
Processing combination: [3 -2 1 ]
Processing combination: [3 -2 2 ]
Processing combination: [3 5 0 ]
Processing combination: [3 5 1 ]
Processing combination: [3 5 2 ]
但是,这有点混乱,需要大量样板代码,为了清楚起见,我宁愿将其移到其他地方。理想情况下,我希望有一个自定义迭代器类,比如my_combination_iterator,它可以让我做的事情更干净,例如:
for (my_combination_iterator it = vv.begin(); it != vv.end(); ++it)
// process combination
到目前为止,我已经查看了Boost iterator_facade。但是我的情况似乎比教程中的情况更复杂,因为我需要一个迭代器来处理 Values 的向量,而不是使用单个值类型来定义自定义迭代器所需的运算符。
如何实现这样的迭代器?
【问题讨论】:
-
我终于有空来尝试实现一个合适的双向组合迭代器。你可以找到它here。我没有使用 boost,所以代码比它可能的更冗长。