I am attempting to create a little program that iterates through a list deleting every third item until only one remains. Unfortunately, I feel as if I am going down a rabbit hole trying to fix my loop process. Good chance I am just thinking about it wrong.
Currently, I think I have two issues. First that my iterator needs to hold it's location after a node is erased, but mostly that once I we get to the end of the list we core dump... I can't seem to catch the iterator at the end.
#include <iostream>
#include <list>
usingnamespace std;
void showRemains(std::list<int> &suit);
int main() {
int size;
std::list<int> numb;
std::list<int>::iterator it;
std::cout << "Please input a number " << endl;
while (!(std::cin >> size) || size < 0 ) {
std::cout << "Please enter a valid number of number!" << std::endl;
std::cin.clear(); // Clear cin stream
std::cin.ignore(50, '\n'); // Ignore previous cin entries
}
std::cout << "Thank you. There are " << size << " numbers." << endl;
for (int i=0; i<size; i++) {
numb.push_back(i+1);
}
showRemains(numb);
it = numb.begin();
while (numb.size() > 1) {
//std::cout << "size " << numb.size() << " it " << *it << endl;
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }
std::cout << "Number #" << *it << " removed." << endl;
numb.erase(it);
//std::cout << "size " << numb.size() << " it " << *it << endl;
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }//advance to next
//std::cout << "size " << numb.size() << " it " << *it << endl;
showRemains(numb);
}
std::cout << "Number #" << numb.front() << " is the final number!!!" << endl;
return 0;
}
void showRemains(std::list<int> &suit) {
std::cout << "Remaining numb" << endl;
for (std::list<int>::iterator i=suit.begin(); i !=suit.end(); i++) {
std::cout << *i << " ";
}
std::cout << endl << endl;
return;
}
Edit: Well i figured out my first issue, I simply had set my iterator to begin() inside my while loop instead of before... I feel silly (updated the code accordingly). I am still getting a segmentation fault and am not sure why my if statements aren't bringing me back the the start.
numb.erase(it);
//std::cout << "size " << numb.size() << " it " << *it << endl;
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }//advance to next
You should never use invalidated iterators. In list iterators to deleted elements are invalidated. Save iterator to another variable, increment main iterator and delete saved one.
That makes sense, though I am not sure I understand the method which this can be done. If I create a second iterator equal to the one to be delete, would it too not be invalid after the delete?
Thanks again, reading comprehension is a good skill to have. Things are working much better now, though I have realized that referencing numb.end() is referring to "blank space" after the last element where I am attempting to compare to the last element.
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }
Is there a trick to checking the end of the list? I attempted to use back() however I get invalid operators with that.