loop through a vector using iterator and test for end of loop-
-
how to test if you reach the end of the loop?
vector<int> mylist; for(std::vector<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) { ... .. . if(......){ // reached end of loop } }
kind regards.
-
@Natural_Bugger said in loop through a vector using iterator and test for end of loop-:
how to test if you reach the end of the loop?
?
Your for loop already tests for the end... -
@Natural_Bugger said in loop through a vector using iterator and test for end of loop-:
how to test if you reach the end of the loop?
?
Your for loop already tests for the end...i guess, i mean when you are handling the last element from the list.
-
i guess, i mean when you are handling the last element from the list.
@Natural_Bugger
Hi
When iterator it points to mylist.end() it wont enter the loop any more
so there is no need to test inside the loop if "at end" -
@Natural_Bugger
Hi
When iterator it points to mylist.end() it wont enter the loop any more
so there is no need to test inside the loop if "at end"@mrjj
hi and thnx,
but how do i know i reached the last "iteration" of the loop?
the last element of "it".if(......){ // last element of "it" }
-
if (it == std::prev(mylist.end()))
-
@Natural_Bugger said in loop through a vector using iterator and test for end of loop-:
but how do i know i reached the last "iteration" of the loop?
You can do it exactly the same as in a for loop which a loop variable
if (it == myList.end() - 1)
or use the solution from @Chris-Kawa
-
if (it == std::prev(mylist.end()))
thnx
-
@Natural_Bugger said in loop through a vector using iterator and test for end of loop-:
but how do i know i reached the last "iteration" of the loop?
You can do it exactly the same as in a for loop which a loop variable
if (it == myList.end() - 1)
or use the solution from @Chris-Kawa
thnx
-
if (it == std::prev(mylist.end()))
@Chris-Kawa
@Christian-Ehrlicheri wanna remove the current element i'm "testing"
http://www.cplusplus.com/reference/vector/vector/erase/
- iterator erase (iterator position);
- iterator erase (iterator first, iterator last);
std::cout << "*it: " << *it << std::endl; // outputs the correct numbers mylist.erase(*it);
error:
error: no matching function for call to ‘std::vector<int>::erase(int&)’
i also tried:
mylist..erase(ar.begin() + *it);
results is fatal crash.
-
*it
is the value pointed to by the iterator.ar.begin() + *it
is nonsense. It advances the iterator by value pointed to byit
.You want to remove the element at iterator so simply
mylist.erase(it);
Keep in mind that erasing the element invalidates the iterator, so if you're doing it in a loop you need to use the iterator returned by
erase
:it = mylist.erase(it);
which erases the element pointed by
it
and then setsit
to point to next element. -
*it
is the value pointed to by the iterator.ar.begin() + *it
is nonsense. It advances the iterator by value pointed to byit
.You want to remove the element at iterator so simply
mylist.erase(it);
Keep in mind that erasing the element invalidates the iterator, so if you're doing it in a loop you need to use the iterator returned by
erase
:it = mylist.erase(it);
which erases the element pointed by
it
and then setsit
to point to next element.@Chris-Kawa
thnx,
ah ... removing the "*", i dind't try that.
at first when i tried to use "if else" statements inside the loop, the compiler couldn't convert "int" into pointer.
so, i though i had to use it.if(mylistr[0] == *it){ std::cout << "*it: " << *it << std::endl; // i do need to use pointer here mylist.erase(mylist.begin()); // remove first mylist.erase(it); // remove current. break; }
i'm existing the loop after i remove the element.
break;
but i still have error on certain conditions, using a list with filled different values, some are valid, some crash.
Program terminated with signal SIGSEGV, Segmentation fault.
-
*it
is the value pointed to by the iterator.ar.begin() + *it
is nonsense. It advances the iterator by value pointed to byit
.You want to remove the element at iterator so simply
mylist.erase(it);
Keep in mind that erasing the element invalidates the iterator, so if you're doing it in a loop you need to use the iterator returned by
erase
:it = mylist.erase(it);
which erases the element pointed by
it
and then setsit
to point to next element.this is how my loops looks like ...
find a pair of matching numbers and remove them.
the find next pair ...
etcint pairs = 0; int counter = 0; do{ if(counter == n){ // n = number of number in list. break; } int counterB = 0; bool remove = false; for(std::vector<int>::iterator it = (mylist.begin()+ 1); it != mylist.end(); ++it) { if(mylist[0] == *it){ std::cout << "*it: " << *it << std::endl; mylist.erase(mylist.begin()); mylist.erase(it); // fails occasionally, but more the the line below. // mylist..erase(mylist.begin() + counterB); // works 100% ... but does not pas all tests. pairs++; break; } if(it == std::prev(mylist.end())){ remove = true; // bool value } counterB++; } if(remove){ mylist.erase(mylist.begin()); // value didn't occur more than once, remove first value. remove = false; } while(true); ... .. .
kind regards.
-
@Natural_Bugger said:
mylist.erase(mylist.begin());
mylist.erase(it); // fails occasionally, but more the the line below.As I said in my previous post
erase
invalidates iterators soit
in the second line points to garbage. For these two lines it's enough to switch them, but you're usingit
couple lines lower and that's also an error. I repeat - whenever you useerase
any iterator you have is invalid.erase
returns an iterator to element after the one that was removed. Keep in mind that the removed element could be the last one so iterator returned fromerase
can beend()
so pointing past the container.By the way, if all you want to do is remove duplicates you can just do:
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
-
@Natural_Bugger said:
mylist.erase(mylist.begin());
mylist.erase(it); // fails occasionally, but more the the line below.As I said in my previous post
erase
invalidates iterators soit
in the second line points to garbage. For these two lines it's enough to switch them, but you're usingit
couple lines lower and that's also an error. I repeat - whenever you useerase
any iterator you have is invalid.erase
returns an iterator to element after the one that was removed. Keep in mind that the removed element could be the last one so iterator returned fromerase
can beend()
so pointing past the container.By the way, if all you want to do is remove duplicates you can just do:
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
how do i store the position of the element, found by the condition of the statement and remove it outside the loop.
if(mylistr[0] == *it){ ... .. . break; }
regards.
-
@Natural_Bugger said:
mylist.erase(mylist.begin());
mylist.erase(it); // fails occasionally, but more the the line below.As I said in my previous post
erase
invalidates iterators soit
in the second line points to garbage. For these two lines it's enough to switch them, but you're usingit
couple lines lower and that's also an error. I repeat - whenever you useerase
any iterator you have is invalid.erase
returns an iterator to element after the one that was removed. Keep in mind that the removed element could be the last one so iterator returned fromerase
can beend()
so pointing past the container.By the way, if all you want to do is remove duplicates you can just do:
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
thnx
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
i need to find a pair, count it, remove that pair, find next pair, count it, etc, etc ... but not all number in the list have a pair.
well ... i just need to count the pairs ... somehow,
so i think the best way to do that, is to find a pair and remove it, so you don't keep finding it over and over. -
@Natural_Bugger said:
mylist.erase(mylist.begin());
mylist.erase(it); // fails occasionally, but more the the line below.As I said in my previous post
erase
invalidates iterators soit
in the second line points to garbage. For these two lines it's enough to switch them, but you're usingit
couple lines lower and that's also an error. I repeat - whenever you useerase
any iterator you have is invalid.erase
returns an iterator to element after the one that was removed. Keep in mind that the removed element could be the last one so iterator returned fromerase
can beend()
so pointing past the container.By the way, if all you want to do is remove duplicates you can just do:
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
in the end, i changed the code to store the positions and remove it outside the loop.
worked fine, but the online compiler didn't pas all tests.
than i tried with the Qt creator IDE and the code return good results.now, I'm trying that what you suggesting.
std::sort(mylist.begin(), mylist.end());
but how to turn
vector::begin vector::end
into a INT values to compare against?
so i don't over run the max length of the list.the code became much much smaller, but also tries to compare value beyond the end of the vector.
int pairs = 0; sort( mylist.begin(), mylist.end() ); int counter = 0; for(auto ii : mylist){ if(mylist.at(counter) == mylist.at(counter + 1)){ std::cout << "found duplicate" << std::endl; pairs++; } counter ++; }
-
@Natural_Bugger said:
mylist.erase(mylist.begin());
mylist.erase(it); // fails occasionally, but more the the line below.As I said in my previous post
erase
invalidates iterators soit
in the second line points to garbage. For these two lines it's enough to switch them, but you're usingit
couple lines lower and that's also an error. I repeat - whenever you useerase
any iterator you have is invalid.erase
returns an iterator to element after the one that was removed. Keep in mind that the removed element could be the last one so iterator returned fromerase
can beend()
so pointing past the container.By the way, if all you want to do is remove duplicates you can just do:
std::sort(mylist.begin(), mylist.end()); mylist.erase(std::unique(mylist.begin(), mylist.end()), mylist.end() );
intput:
20 // number of value 4 5 5 5 6 6 4 1 4 4 3 6 6 3 6 1 4 5 5 5
sorting:
std::sort(mylist.begin(), mylist.end());
atfter sorting:
1 1 3 3 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6
int example(vector<int> mylist){ sort( ar.begin(), ar.end() ); int pairs = 0; unsigned long int counterC = 0; do{ if(counterC == (mylist.size() - 1)){ std::cout << "end loop" << std::endl; break; } else { do { if(mylist[0] == mylist[1]) { // equal; mylist.erase(mylist.begin()); // erase first element, than try to erase next ...... it works ... but partially ... at first iteration it does remove the first 2 element, but not on the following. mylist.erase(mylist.begin()); // breaks "sometimes" the code according to Qt creator debug // Program terminated with signal SIGSEGV, Segmentation fault. std::cout << "found equals" << std::endl; pairs++; break; } else { // remove std::cout << "found soletary" << mylist.at(0) << std::endl; ar.erase(ar.begin()); break; } } while(true); } for(auto ii : mylist) { std::cout << "ii: "<< ii << " "; } std::cout << std::endl; std::cout << "counterC: " << counterC << std::endl; counterC++; } while(true); return pairs; }
i also tried:
mylist.erase(mylist.begin(), mylist.begin()+1);
this is the total output:
found equals ii: 1 ii: 3 ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 0 found soletary1 ii: 3 ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 1 found equals ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 2 found soletary3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 3 found equals ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 4 found equals ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 5 found equals ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 6 found equals ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 7 found soletary4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 8 found equals ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 9 found equals ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 10 found equals ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 11 found equals ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 12 found equals ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 13 found soletary5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 14 found equals ii: 6 ii: 6 ii: 6 ii: 6 counterC: 15 found equals ii: 6 ii: 6 ii: 6 counterC: 16 found equals ii: 6 ii: 6 counterC: 17 found equals ii: 6 counterC: 18 found equals counterC: 19
-
intput:
20 // number of value 4 5 5 5 6 6 4 1 4 4 3 6 6 3 6 1 4 5 5 5
sorting:
std::sort(mylist.begin(), mylist.end());
atfter sorting:
1 1 3 3 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6
int example(vector<int> mylist){ sort( ar.begin(), ar.end() ); int pairs = 0; unsigned long int counterC = 0; do{ if(counterC == (mylist.size() - 1)){ std::cout << "end loop" << std::endl; break; } else { do { if(mylist[0] == mylist[1]) { // equal; mylist.erase(mylist.begin()); // erase first element, than try to erase next ...... it works ... but partially ... at first iteration it does remove the first 2 element, but not on the following. mylist.erase(mylist.begin()); // breaks "sometimes" the code according to Qt creator debug // Program terminated with signal SIGSEGV, Segmentation fault. std::cout << "found equals" << std::endl; pairs++; break; } else { // remove std::cout << "found soletary" << mylist.at(0) << std::endl; ar.erase(ar.begin()); break; } } while(true); } for(auto ii : mylist) { std::cout << "ii: "<< ii << " "; } std::cout << std::endl; std::cout << "counterC: " << counterC << std::endl; counterC++; } while(true); return pairs; }
i also tried:
mylist.erase(mylist.begin(), mylist.begin()+1);
this is the total output:
found equals ii: 1 ii: 3 ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 0 found soletary1 ii: 3 ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 1 found equals ii: 3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 2 found soletary3 ii: 4 ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 3 found equals ii: 4 ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 4 found equals ii: 4 ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 5 found equals ii: 4 ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 6 found equals ii: 4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 7 found soletary4 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 8 found equals ii: 5 ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 9 found equals ii: 5 ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 10 found equals ii: 5 ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 11 found equals ii: 5 ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 12 found equals ii: 5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 13 found soletary5 ii: 6 ii: 6 ii: 6 ii: 6 ii: 6 counterC: 14 found equals ii: 6 ii: 6 ii: 6 ii: 6 counterC: 15 found equals ii: 6 ii: 6 ii: 6 counterC: 16 found equals ii: 6 ii: 6 counterC: 17 found equals ii: 6 counterC: 18 found equals counterC: 19
@Natural_Bugger
In some shape or form: when iterating through the elements looking at adjacent ones, you must either omit/skip the first and start at the second one (if you compare elements against the one to the left), or omit/skip the last one and stop at the penultimate one (if you compare elements against the one to the right). -
@Natural_Bugger
In some shape or form: when iterating through the elements looking at adjacent ones, you must either omit/skip the first and start at the second one (if you compare elements against the one to the left), or omit/skip the last one and stop at the penultimate one (if you compare elements against the one to the right).thank you for the reply.
well, i saw that some people or most did that for the same problem, but in Java and apparently, they also sorted the "array/map" like Chris Kawa mentioned it worked for them.
so i tried that as well in c++.bit i also think the "solutions" they published do not work, because they only compare 2 (if) or else (nothing). no taking in consideration if the list of values is either even or uneven in length or the numbers of equal value is either even or uneven.
now i'm using nested "Do While" loops instead of For loop in combination with Iteration.
what to do next?.