简体   繁体   中英

compare successive elements in Vector by using Iterator

Problem: Check successive elements in vectors 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?
  • I don't want to use the second for loop in the source code because vector size might change. 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. You would need the condition to be i+1 < v.size()

  • by using for(auto &i: v)how can I use the index in order to compare two successive elements?

Because std::vector is guaranteed to have contiguous storage it is possible to access the next element when using a range-based for loop:

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. 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.

  • I don't want to use the second for loop in the source code because vector size might change. 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.

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 .

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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