Looping a list

May 31, 2014 at 5:26pm
Hello,

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.

Any help would be appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <list>

using namespace 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.
Last edited on May 31, 2014 at 7:05pm
May 31, 2014 at 6:52pm
1
2
3
4
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.
May 31, 2014 at 7:21pm
Thanks MiiNiPaa,

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?
May 31, 2014 at 7:28pm
You will use it only to delete and then won't touch it again.
May 31, 2014 at 7:43pm
If I understand correctly, it would be something like
1
2
3
		std::cout << "Number #" << *it << " removed." << endl;
		std::list<int>::iterator del = it;
		numb.erase(del);


But this seems to kill both it and del. So I am pretty sure I am not on the right track.
May 31, 2014 at 7:46pm
MiiNiPaa wrote:
Save iterator to another variable, increment main iterator and delete saved one.
1
2
3
std::list<int>::iterator del = it;
++it
numb.erase(del);
//or
std::list<int>::iterator del = it++;
numb.erase(del);
May 31, 2014 at 8:30pm
or..
numb.erase(it++);

or...
it = numb.erase(it);
Jun 1, 2014 at 12:37am
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.

Jun 1, 2014 at 1:14am
Got it!

By advancing the iterator, then checking for the end I am in the right spot when I check.

		it++; 
		if (it == numb.end() ) { it = numb.begin(); }


Thanks for the help everyone. This one is in the bag!
Topic archived. No new replies allowed.