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

时间:2015-02-10 15:26:10

标签: c++ vector iterator

我正在尝试从 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 的迭代器吗?或者还有另一种选择吗?

修改
嘿伙计们,似乎我一直在问错了问题。我已经标出了这个问题的答案,很快就会发布另一个问题 感谢您对我的问题的快速回复!

5 个答案:

答案 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符合要求,那么为什么不让下一个人的代码易于阅读?