Click here to Skip to main content
15,885,689 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This is a continuation from my previous question Hall of Fame[^]
By following the advice from Richard MacCutchan[^], I tried using vector in my implementation of Hall Of Fame which has name and score.
The name should not have duplicate and score should be sorted.
However here I'm stuck.
C++
bool myfunction(std::pair<string, unsigned int> rhs, std::pair<string,unsigned int> lhs) {
	return ( rhs.second > lhs.second );
}
C++
std::vector < std::pair<string, unsigned int>> hall;
hall.push_back(std::make_pair("One", 50));
hall.push_back(std::make_pair("Two", 30));
hall.push_back(std::make_pair("Three", 10));
hall.push_back(std::make_pair("Two", 30));
hall.push_back(std::make_pair("Three", 20));
std::sort(hall.begin(), hall.end(), myfunction);
for ( auto c : hall ) {
	cout << c.first << " " << c.second << endl;
}
for ( auto a : hall ) {
	for ( auto b : hall ) {
		if ( ( a.first == b.first ) && ( a.second != b.second ) ) {
			if ( a.second > b.second ) {
				hall.erase(b);//???
			}
		}
	}
}

I've copy the vector into a set<pair><string,unsigned>> and it solve problem with duplicated entry ("Two",30).

How can I remove the pair("Three",10) from the vector.
Whatever loop / iterator trick that I know do not work.
In one of tries versions (using iterator) I managed to erase the pair("Three",10) but it failed in the next step (using debugger) because (I think) the iterator pointing to invalid location in the next iteration or vector size changed.

I'm a newbie to programming
I really think I missed something simple here.
What should I do. Please teach me a bit.

What I have tried:

after sorting the vector
-I've tried erasing using iterator pointing b.
-I've tried using another loop (int i=0;i<hall.size();>-unsuccessful using std::find to search for pairs that have same string but different value (hence the nested a and b for loop).
-reading cplusplus.com about it
Posted
Updated 19-Feb-16 8:03am

1 solution

removing duplicates is tricky, because you alter the vector content on-the-fly.
The range loop is elegant but simply not suited for such a job. Try, for instance

C++
auto itm = hall.begin();

while(itm != hall.end())
{

  auto itn = hall.end();
  while(--itn != itm)
  {
    if ( itm->first == itn->first && itm->second == itn->second )
      hall.erase(itn);
  }
  ++itm;
}


Optimize the code for the sorted vector is left as exercise.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 19-Feb-16 15:08pm    
5ed. Generally, it's about traversing a set of elements while modifying the same set. So, the question is: what are you traversing? In certain cases, it can be done, by doing it with care, which is shown in your sample.
—SA
CPallini 19-Feb-16 15:26pm    
Thank you.
Are Riff 19-Feb-16 16:02pm    
The same thing happen. Just after the hall.erase(itn); and when through the next loop crashes happen with message: Vector iterator is not decrementable.

Did I choose the wrong container?
What should I do if I just want a simple list of name and score sorted as it should in Hall Of Fame (without duplicates). The idea look innocent enough.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900