简体   繁体   English

使用迭代器比较Vector中的连续元素

[英]compare successive elements in Vector by using Iterator

Problem: Check successive elements in vectors if v[i] < v[i+1] + 1 问题: if v[i] < v[i+1] + 1检查向量中的连续元素

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int>v{1,2,3,4,5,6,7,8,9,10};
    for(auto &i: v)
    {
        cout << (i+1) << endl;
    }
    //SIMILAR TO THIS FOR LOOP
    for(int i = 0; i < v.size() - 1;i++)
    {
        if(v[i] < v[i+1] + 1){cout << "ok" << endl;}
    }
    return 0;
}

Questions: 问题:

  • by using for(auto &i: v) how can I use the index in order to compare two successive elements? 通过使用for(auto &i: v)我如何使用索引来比较两个连续的元素?
  • I don't want to use the second for loop in the source code because vector size might change. 我不想在源代码中使用第二个for循环,因为矢量大小可能会改变。 By using auto i don't have to worry if elements are erased and the vector is resized is that right? 通过使用自动,我不必担心元素是否被删除以及矢量是否已调整大小,对吗?
for(int i = 0; j < v.size();i++)
{
    if(v[i] < v[i+1] + 1){cout << "ok" << endl;}
}

This loop has undefined behaviour, you access v[i+1] when i is the last index. 此循环具有未定义的行为,当i是最后一个索引时,您访问v[i+1] You would need the condition to be i+1 < v.size() 您需要条件为i+1 < v.size()

  • by using for(auto &i: v)how can I use the index in order to compare two successive elements? 通过使用for(auto&i:v),如何使用索引来比较两个连续的元素?

Because std::vector is guaranteed to have contiguous storage it is possible to access the next element when using a range-based for loop: 由于保证std::vector具有连续存储,因此在使用基于范围的for循环时可以访问下一个元素:

for (auto& i : v)
  if (i < *(&i+1) + 1) {cout << "ok" << endl;}

However this has the same problem as your for loop, it will access past-the-end of the vector, and in this case there is no way to stop it because you can't use a range-based for loop if you want to stop iteration before the end of the range. 但是,这与for循环有相同的问题,它将访问向量的尾端,在这种情况下,无法停止它,因为如果您想使用基于范围的for循环,在范围结束之前停止迭代。 You would need to do: 您需要执行以下操作:

size_t count = 0;
for (auto& i : v)
  if (++count < v.size() && i < *(&i+1) + 1) {cout << "ok" << endl;}

And at this point you might as well just use a normal for loop, it's simpler and clearer. 在这一点上,您最好只使用普通的for循环,它更简单明了。

  • I don't want to use the second for loop in the source code because vector size might change. 我不想在源代码中使用第二个for循环,因为矢量大小可能会改变。 By using auto i don't have to worry if elements are erased and the vector is resized is that right? 通过使用自动,我不必担心元素是否被删除以及矢量是否已调整大小,对吗?

No! 没有! You must not use range-based for loops for anything funky like iterating over a vector that are being modified, it just goes from the first element to the last element of a fixed range, nothing fancy. 对于任何时髦的事情,例如迭代被修改的向量,都不能使用基于范围的for循环,它只是从固定范围的第一个元素到最后一个元素,没有花哨的地方。

If you try to use it while the vector is being modified then either it will go off the end of the vector, or if the vector grows and reallocates then the iterators used behind the scenes by the range-based loop will become invalidated. 如果在修改向量时尝试使用它,则它将离开向量的结尾,或者如果向量增长并重新分配,则基于范围的循环在幕后使用的迭代器将变得无效。

If you need to do something more complicated than just visiting every element in turn then do not use a range-based for loop . 如果您需要做的不仅是依次访问每个元素,还需要进行更复杂的操作,则不要使用基于范围的for循环

Or you could keep it simple. 或者,您可以保持简单。 If you have to declare a variable outside the loop anyway, you could then just write: 如果仍然必须在循环外声明变量,则可以这样写:

int index = 0;  
for (auto &i : v)
{
    if (index + 1 < v.size() && i < v[++index] + 1) { cout << "ok" << endl; }
}

I think v[++index] could be a little more faster than *(&i+1) + 1 . 我认为v[++index]可能比*(&i+1) + 1快一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM