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:
for(auto &i: v)
how can I use the index in order to compare two successive elements? 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.