I want to make a table of letter frequency, just like this
So, I have variable str
that contains some text, and I have map<char, int> m
, that contains number of occurrences of each letter.
So I have something like that:
vector<char> get_rank(const string& str)
{
map<char, int> m;
for (char i = 'a'; i <= 'z'; i++)
m[i] = 0;
for (char ch : str)
m[ch]++;
for (auto& it : m)
v.push_back(it.first);
return v;
}
But map is ordered by keys, not by values. Is there a way to "overload" the comparator of map to order each element by value? If the answer is no, how can I implement the same idea but with the same elegancy. Because every idea I have seems a little dull and rough.
It is not possible to sort a map with respect to its mapped values. The order of elements of a map is managed by the map according to its comparator which only considers keys.
However, you do not need a map to count frequencies when the keys are contiguous and of limited range.
Instead of a map, use a std::vector<letter_and_count>
with
struct letter_and_count {
char letter;
int count = 0;
};
Initialize the vector with elements with letter
initialized to a
till z
then increment v[ i - 'a']
when you encounter the letter i
in the string. Then use std::sort
to sort the vector according to the count
member.
PS: Note comments below. The letters a
till z
are not necessarily contiguous. However (idea also from eerorika) you can use a simple lookup table:
std::string alphabet{"abcdefghijklmnopqrstuvwxyz"};
Then first find the letter in that alphabet
and use its index in the alphabet for the counting.