-2

What is the best way to erase an element based on the code below? The internal for loop needs to finish before I can erase the biggest number found. While "problem-with-stdmapiterator-after-calling-erase" explains how erase works, I cannot seem to be able to make it work. An example based on the code below would be appreciated.

map<string,int> test;
void sort_print()
{
    int biggestNum = 0;
    string word;

    for(int i = 0; i < WORDS_TO_FIND; i++)
    {
        for(auto it = test.begin(); it != test.end(); ++it )
        {
            if (it->second > biggestNum)
            {
                biggestNum = it->second;
                word = it->first;
            }

        }
        test.erase(word);
        cout << word + ": " << biggestNum << endl;
    }
}

Interesting enough, when I go to main (after having removed the first loop from the function above and do the following.. then it works but why?:

for(int i = 0; i < WORDS_TO_FIND; i++)
{
    test.erase(sort_print());
}
George
  • 29
  • 5
  • You should use the return value of `test.erase(it)` – drescherjm Mar 10 '18 at 15:51
  • After you `erase(it)` `it` is invalid and so is the subsequent `++it`. – nwp Mar 10 '18 at 15:52
  • 1
    [Possible dupe](https://stackoverflow.com/questions/4636182/problem-with-stdmapiterator-after-calling-erase). – user202729 Mar 10 '18 at 15:52
  • 2
    Possible duplicate of [Problem with std::map::iterator after calling erase()](https://stackoverflow.com/questions/4636182/problem-with-stdmapiterator-after-calling-erase) – nwp Mar 10 '18 at 15:53

1 Answers1

0

If all you want to do is erase the map element whose value is the highest then:

map<string, int> test;

void sort_print()
{
    int biggestNum = 0;
    string word;

    for (auto it = test.begin(); it != test.end(); it++)
    {
        if (it->second > biggestNum)
        {
            word = it->first;
        }
    }
    cout << word + ": " << biggestNum << endl;
    test.erase(word);
}

No need for two loops, and no need for:

biggestNum = it->second;
Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • Thank you but I am afraid this doesn't seem to delete the element after having tried it. Therefore, when it goes to the external for loop again, it will print the same result as the last time. Also, note that the erase should be called when the internal loop finishes as we are looking for the biggest number. – George Mar 10 '18 at 16:16
  • Thank you again, I need it for an X amount of words with the biggest number ordered. So every time I find the biggest word (based on its int value) I erase it and do the loop again. Based on your example above (after you edited it), I have tried that but it still doesn't erase the element interesting enough... but I would still need the second loop regardless based on my above explanation. – George Mar 10 '18 at 16:33
  • @George I don't understand what you mean it doesn't erase it. map::erase does erase the element at the iterator you give it. If you want to for example remove the top five highest numbers in your map, call the function five times. If you want you want it specifically done in one function call tell me. – Zebrafish Mar 10 '18 at 16:37
  • The external loop, will loop 20 times so that it can find the words in the map with the biggest integer values. When the internal loop finishes, I want to erase the value so that when it executes the second time, it won't find the same word. Calling the test.erase(word), does not remove the value so I am getting the same result 20 times. Having said that, removing the external loop (which loops 20 times) and moving it to main and calling the erase from there, then it removes the value as expected and I get correct results. why that happens? – George Mar 10 '18 at 16:42
  • I knew it was something silly... forgot to reset the counter biggestNum. thank you for your help. – George Mar 10 '18 at 16:49