How to print a map sorted by value

Hi I'm working with the book C++ Accelerated, and working with maps. I have defined a map<string, int> where string are words and int are how many times they appear in a input.

I'm trying to solve how I can print the map so it ordered after how many times the word appear. I need some help with the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void print_new(map<string, int>& m) {
	count it, itr, max;
	itr = m.begin(), max = m.begin();
	int i = m.size();
	while ( i > 0 ) {
		for ( it = m.begin(); it != m.end(); ++it) {
			++itr;
			if ( compare(it->second, itr->second) ) {
				++max;
			}
		}
		cout << max->first << "\t" << max->second << endl;
		m.erase(max);
		--i;
	}
}

and count is defined as:
 
typedef map<string, int>::iterator


My problem is I can't erase the key and it's value, so I don't get the same key again. I only get a error when i try to run the program..?
Last edited on
Your logic looks somewhat strange to me...You seem to have too many loops going on...

What I would do is (maybe this is a waste of time and someone has a much better method then me...but) split up the map into it two component vectors, making them each be related (i.e. vector<string> of m.firsts, and vector<int> of m.seconds...) and then do your sorting on the ints, and switching the vector of strings as needed. Then put the data back into the map.
I would use a boost::multi_index_container which is the same as a map but allows you to sort by key or value. The nice thing is it should drop right into your code without much difficulty.
I have thought about doing both, but I think the learning objective is to make a function which sort by value instead. I have tried some different things, and have almost (I think) got it. But there's still some problems with my loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void print_new(const map<string, int>& m) {
	iter it, itr, max;
	map<string, int> ret;
	ret = m;
	int i = m.size();
	while ( i > 0 ) {
		itr = ret.begin(), max = ret.begin(), it = ret.begin();
		int j = ret.size();
		while ( j > 0 ) {
			if ( compare(itr->second, it->second) ) {
				max = itr;
			}
			++itr;
			--j;
		}
		cout << max->first << "\t" << max->second << endl;
		ret.erase(max);
		--i;
	}
}

And as before iter is defined as map::itererator. And the compare function is:
1
2
3
bool compare(int i, int j) {
	return i > j;
}


Now I get something that look a bit like it's sorted, but the second while loop isn't right?
I have solved my problem!
I had to change the iterator it too, so it didn't get compared with the initial... Hope this might help others... Here is the final function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void print_new(const map<string, int>& m) {
	iter it, itr, max;
	map<string, int> ret;
	ret = m;
	int i = m.size();
	while ( i > 0 ) {
		itr = ret.begin(), max = ret.begin(), it = ret.begin();
		int j = ret.size();
		while ( j > 0 ) {
			if ( compare(itr->second, it->second) ) {
				max = itr;
				it = itr;
			}
			++itr;
			--j;
		}
		cout << max->first << "\t" << max->second << endl;
		ret.erase(max);
		--i;
	}
}

And the compare function:
1
2
3
bool compare(int i, int j) {
	return i > j;
}

And as before iter is defined as a map::iterator...
Last edited on
I'm just wondering...why do you have a compare function? You know the > < etc work on iterators?
I really don't know... I sorted some vector strings earlier, I might still have that in mind..?
But thanks :)
Topic archived. No new replies allowed.