Reputation: 714
I'm trying to iterate a vector from the nth element onwards. Not sure how should i go about doing this.
I have a vector A and B. My vector A has 10 elements of PC1-PC10 and my vector B has 20 elements of User1-User20.
So what I want to do is that when both my vector A and B reaches the 10th element, meaning to say the last element for vector A, I want to repeat iterating vector A but start iterating vector B from the 11th element so that I can do some stuff with it.
Below is the simplified code that I came up with but technically its about the same thing:
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
}
}
Should I mess with the iterator for vector B? Or is there another alternative?
EDIT
It seems that I have been asking the wrong question after all. I have marked the answer to this question and will be posting another shortly. Thanks for the quick response to my question!
Upvotes: 3
Views: 3648
Reputation: 6561
I actually prefer to manually iterate over vectors pre-C++11 because it looks way cleaner and more readable than iterators
:
for (unsigned int i = 0; i < my_vector.size(); i++) {
my_vector[i]; //Do Something
}
You can specify the range you want to iterate over simply by modifying the for loop conditional (i.e. unsigned int i = n
)
Edit: Before downvoting actually read my entire answer. Using iterators on vectors is overly verbose and makes your code virtually unreadable. If there is a legitimate reason this method should not be used in favor of iterators, then please leave a comment.
Most people aren't looking for an ultra-generic, drop-in-any-container solution. Most people know they need a dynamic list, vector
fits the bill, so why not make your code easy to read for the next guy?
Upvotes: -1
Reputation: 9617
You don't need to change the iterator for B, it will automatically continue with 11th element. But you need to restart iteration on A at the beginning of the for loop (or you would work with a.end()
which is not a valid element):
if (a == vecA.end()) {
a = vecA.begin();
}
Also you should iterate over both but check for end on b
only; if you check on a
, the for
would end before the if
would turn true:
for (auto a = vecA.begin(), b = vecB.begin(); b != vecB.end(); ++a, ++b)
You can see the whole code here.
Upvotes: 0
Reputation: 727047
The if
condition inside the nested loop will never be true, because it conflicts with the loop condition:
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; a++) {
// This check ----------------------------------^^^^^^^^^^^^^^^
// guarantees that this will never succeed:
// vvvvvvvvvvvvvvv
if (a == vecA.end()) {
...
}
}
You should rewrite the code like this:
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);
}
The call of ++b
can be moved into the loop header.
Note the use of std::next
: although
b = vecB.begin() + 10;
compiles for vectors, it is not guaranteed for all kinds of containers. Use std::next
instead:
b = std::next(vecB.begin(), 11);
Note: This code makes an assumption that vecB
has at least 11 elements more than vecA
does. This may be OK if you check that assumption before entering the loop. If this assumption is broken, the code would have undefined behavior.
Upvotes: 4
Reputation: 238461
Others have already answered how to reset or advance an iterator, so I'll just answer, how to solve your problem in a simpler way. It's much simpler to iterate two vectors in parallel using the index rather than two iterators:
// 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()];
}
Pay attention to how the smaller vector is iterated using the remainder operator.
Upvotes: 1
Reputation: 206717
In addition to using std::next
, as shown in the answer by @dasblinkenlight, you can also use std::advance
.
b = vecB.begin();
std::advance(b, 10);
Upvotes: 0