How to order a map by copying its contents into a vector?

Below is my current code. It prints out all of the characters in the specified file but not in order. I have been looking online and have noticed that people suggest to copy the map into a vector to sort it. However, I am having a problem successfully implementing this and was looking for some assistance.

int main()
{
map<char, int> letters;
map<char, int>::iterator i;
string input;
ifstream file;

file.open("ToCompress.txt");

if (file.fail())
{
printf("Error opening file");
exit(1);
}

while (!file.eof())
{
getline(file, input);
cout << input << endl;
}

for (auto c : input)
{
++letters[c];

}

for (i = letters.begin(); i != letters.end(); ++i)
{
cout << "\n" << i->first << " occurs " << i->second << " times \n ";
}

return 0;

file.close();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>

int main()
{
    const std::map< char, int > char_cnt { {'m',2}, {'a',6}, {'p',4}, {'b',3}, {'y',1}, {'g',5} } ;

    // the map is already sorted on the key (char)
    for( const auto& pair : char_cnt ) std::cout << pair.first << ' ' << pair.second << '\n' ;
    std::cout << "--------------------\n" ;

    // to sort on the mapped type (int)
    {
        std::vector< std::pair< int, char > > vec ; // note: char and int are flipped
        for( const auto& pair : char_cnt ) vec.emplace_back( pair.second, pair.first ) ;
        std::sort( vec.begin(), vec.end() ) ;
        for( const auto& pair : vec ) std::cout << pair.second << ' ' << pair.first << '\n' ;
        std::cout << "--------------------\n" ;
    }
}

http://coliru.stacked-crooked.com/a/88684ff976e92a42
First, to make this easier for us to read and comment on, please go back and edit your post and add code tags. Highlight the code in your post and click the Format button that looks like "<>". This will display indentation and provide line numbers.

As far as your problem, what input are you using, what output are you getting and what output are you expecting? Your code looks correct to me , but I'm not sure I know exactly what you are looking for.

In any case, I doubt you need to copy anything to a vector. In the most obvious case the map should take care of the sorting for you. I guess it depends on what you are actually trying to sort.

Edit: Seeing JLBorges' post (I got ninja'd), I can see what you may have been trying to do. I didn't think about printing out the characters in order of frequency.
Last edited on
In the original code, this looks wrong, in several ways:
1
2
3
4
5
6
7
8
9
10
while (!file.eof())
{
    getline(file, input);
    cout << input << endl;
}

for (auto c : input)
{
    ++letters[c];
}


Don't loop on eof(), instead put the input operation in the while loop condition:
1
2
3
4
while ( getline(file, input) )
{
    cout << input << endl;
}


Also, if the intention is to process all the characters in the file, this loop:
1
2
3
4
for (auto c : input)
{
    ++letters[c];
}
needs to be inside the main while loop:
1
2
3
4
5
6
7
8
    while (getline(file, input))
    {
        std::cout << input << std::endl;
        for (auto c : input)
        {
            ++letters[c];
        }        
    }

What I am trying to do is to print a string taken from a file I have in the order of frequency of characters. I am currently getting all of the correct frequencies of characters its just that they are unordered and that is what I need help with.
Topic archived. No new replies allowed.