A “map” is a
mapping, more commonly called an
associative array in CS.
It is a (key → value) lookup table.
Given a key, you can access an associated value.
For example, the following array is a mapping of number value to name:
1 2 3 4
|
const char* number_to_name[] =
{
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"
};
|
I can get a number’s name by looking it up by the number’s value:
|
std::cout << "A newborn is " << number_to_name[ 0 ] << " years old.\n";
|
The problem with a simple C-style array is that it can only use consecutive integer values as keys. Sometimes you need something a little more sophisticated.
For example, suppose I want to keep the age of people by name:
"Sandy" →
19
"Jacob" →
18
"Katie" →
20
There is no simple way to do this. Fortunately, the Standard Library helps, by providing several associative array types. The oldest is the
std::map.
1 2 3 4 5 6
|
std::map <std::string, unsigned> person_to_age
{
{ "Sandy", 19 },
{ "Jacob", 18 },
{ "Katie", 20 }
};
|
Now I can look things up with the same ease:
|
std::cout << "Sandy is " << person_to_age[ "Sandy" ] << " years old.\n";
|
Now, for your problem. You seem to be doing it the hard way. You are dancing around the idea of a
histogram.
A histogram is a mapping of (value → number of times value appears). Since you are looking for the element with the maximum unique number of appearances, I recommend using a
std::multimap, so that you can reverse the mapping (since the number of times a value appears might not be unique).
See
https://stackoverflow.com/a/5056797/2706707 for the essentials (and from where I got the following functions).
1 2 3 4 5 6
|
#include <algorithm>
#include <ciso646>
#include <iostream>
#include <map>
#include <utility>
#include <vector>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
template<typename A, typename B>
std::pair<B,A> flip_pair(const std::pair<A,B> &p)
{
return std::pair<B,A>(p.second, p.first);
}
template<typename A, typename B>
std::multimap<B,A> flip_map(const std::map<A,B> &src)
{
std::multimap<B,A> dst;
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()),
flip_pair<A,B>);
return dst;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
int main()
{
std::vector<int> elementList;
...
// First, we histogram the elementList
std::map<int,int> histogram;
for (int elt : elementList)
histogram[elt]++;
// Now we want the histogram sorted by the frequency that elements appear
auto frequencyList = flip_map( histogram );
// The very last element (being the largest key in the default ordering) will be
// the "majority element" IFF:
// • the key (frequency) is greater than the (size of the elementList) div 2, and
// • the key appears exactly once
if (frequencyList.size())
{
int frequency, element;
std::tie( frequency, element ) = *frequencyList.rbegin();
if ( (frequency > elementList.size() / 2) and (frequencyList.count( frequency ) == 1) )
{
std::cout << "The majority element is " << element << ".\n";
}
else
{
std::cout << "There is no majority element.\n";
}
}
else
{
std::cout << "There were no elements...\n";
}
}
|
Disclaimer: I have not compiled and executed this, so typos may have occurred.
Hope this helps.