我正在尝试从 nth 元素开始迭代向量。不确定我该怎么办呢。
我有一个向量 A 和 B 。我的vector A 有10个元素 PC1-PC10 ,我的vector B 有20个元素 User1-User20 。
所以我想做的是当我的矢量 A 和 B 都到达第10个元素时,意味着说矢量的最后一个元素 A ,我想重复迭代向量 A ,但是从 11th 元素开始迭代向量 B ,这样我就可以用它做一些事情。
下面是我提出的简化代码,但从技术上来说它是关于同样的事情:
vector<string>::iterator b = vecB.begin();
for (int i = 1; i < 2; i++) {
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; a++) {
if (a == vecA.end()) {
b = vecB.begin() + 10; //here the iterator for verB should start from the 11th element
}
++b
}
}
我应该使用vector B 的迭代器吗?或者还有另一种选择吗?
修改
嘿伙计们,似乎我一直在问错了问题。我已经标出了这个问题的答案,很快就会发布另一个问题
感谢您对我的问题的快速回复!
答案 0 :(得分:3)
嵌套循环中的if
条件永远不会为真,因为它与循环条件冲突:
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; a++) {
// This check ----------------------------------^^^^^^^^^^^^^^^
// guarantees that this will never succeed:
// vvvvvvvvvvvvvvv
if (a == vecA.end()) {
...
}
}
你应该重写这样的代码:
vector<string>::iterator b = vecB.begin();
// Check that vecB has sufficient number of elements before entering the loop.
for (int i = 1 ; i < 2 ; i++) {
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; ++a, ++b) {
...
}
// At this point we know for sure that a == vecA.end(),
// because it is a post-condition of the for loop above.
b = std::next(vecB.begin(), 11);
}
++b
的调用可以移入循环标题。
请注意使用std::next
:尽管
b = vecB.begin() + 10;
为向量编译,不保证所有类型的容器。请改用std::next
:
b = std::next(vecB.begin(), 11);
注意:此代码假设vecB
至少有11个元素,而不是vecA
。如果在进入循环之前检查该假设,这可能没问题。如果这个假设被破坏,代码就会有不确定的行为。
答案 1 :(得分:1)
其他人已经回答了如何重置或推进迭代器,所以我只想回答,如何以更简单的方式解决问题。使用索引而不是两个迭代器并行迭代两个向量要简单得多:
// assumes vecB is bigger than vecA as described in the question
for (std::size_t i = 0; i < vecB.size(); i++) {
auto user = vecB[i];
auto pc = vecA[i % vecA.size()];
}
注意如何使用余数运算符迭代较小的向量。
答案 2 :(得分:0)
除了使用std::next
之外,如@dasblinkenlight的回答所示,您还可以使用std::advance
。
b = vecB.begin();
std::advance(b, 10);
答案 3 :(得分:-1)
您不需要更改B的迭代器,它将自动继续使用第11个元素。但是你需要在for循环开始时重新启动A上的迭代(或者你将使用a.end()
这不是一个有效的元素):
if (a == vecA.end()) {
a = vecA.begin();
}
此外,您应该迭代两者,但仅在b
上检查结束;如果您查看a
,则for
会在if
转为真之前结束:
for (auto a = vecA.begin(), b = vecB.begin(); b != vecB.end(); ++a, ++b)
您可以看到整个代码here。
答案 4 :(得分:-1)
我实际上更喜欢手动迭代C ++ 11前的矢量,因为它看起来比iterators
更清晰,更易读:
for (unsigned int i = 0; i < my_vector.size(); i++) {
my_vector[i]; //Do Something
}
您可以通过修改for循环条件(即unsigned int i = n
)来指定要迭代的范围
编辑:在downvoting之前,实际上阅读了我的整个答案。在向量上使用迭代器过于冗长,使您的代码几乎无法读取。如果有正当理由不应该使用此方法来支持迭代器,那么请发表评论。
大多数人都没有寻找超通用的,随意插入容器的解决方案。大多数人都知道他们需要一个动态列表,vector
符合要求,那么为什么不让下一个人的代码易于阅读?