从第 n 个元素开始迭代向量

Start iterating vector from the nth element

我正在尝试从 nth 元素开始迭代一个向量。不确定我应该怎么做。

我有一个向量 AB。我的矢量 A 有 10 个元素 PC1-PC10 我的矢量 B 有 20 个元素 用户1-用户20.
所以我想做的是当我的向量 AB 都到达第 10 个元素时,意思是说向量 [= 的最后一个元素21=]A,我想重复迭代向量 A 但从第 11 开始迭代向量 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
    }
}

我应该弄乱向量 B 的迭代器吗?或者有其他选择吗?

编辑
看来我终究是问错了问题。我已经标记了这个问题的答案,很快就会发布另一个。感谢您对我的问题的快速回复!

您无需更改 B 的迭代器,它会自动从第 11 个元素继续。但是您需要在 for 循环开始时在 A 上重新开始迭代(或者您将使用 a.end() 这不是有效元素):

if (a == vecA.end()) {
    a = vecA.begin();
}

您还应该遍历两者,但只检查 b 上的结束;如果您检查 afor 将在 if 变为真之前结束:

for (auto a = vecA.begin(), b = vecB.begin(); b != vecB.end(); ++a, ++b)

你可以看到完整的代码here

嵌套循环内的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 至少比 vecA 多 11 个元素。如果您在进入循环之前检查该假设,这可能没问题。如果这个假设被打破,代码将有未定义的行为。

除了使用std::next,如@dasblinkenlight的回答所示,还可以使用std::advance.

b = vecB.begin();
std::advance(b, 10);

我实际上更喜欢手动迭代 C++11 之前的向量,因为它看起来比 iterators:

更清晰、更易读
for (unsigned int i = 0; i < my_vector.size(); i++) {
    my_vector[i]; //Do Something
}

您可以简单地通过修改 for 循环条件(即 unsigned int i = n)来指定要迭代的范围

编辑:在投票之前实际上阅读了我的整个答案。在向量上使用迭代器过于冗长并且使您的代码几乎不可读。如果有正当理由不应使用此方法来支持迭代器,请发表评论。

大多数人并不是在寻找超通用的、可放入任何容器的解决方案。大多数人都知道他们需要一个动态列表,vector 符合要求,那么为什么不让您的代码易于下一个人阅读呢?

其他人已经回答了如何重置或推进迭代器,所以我只回答,如何以更简单的方式解决您的问题。使用索引而不是两个迭代器并行迭代两个向量要简单得多:

// 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()];
}

注意较小的向量是如何使用余数运算符迭代的。