I have some numbers stored in a vector . I want to find which number appears most in the vector.
Is there any easy/fast algorithm (STL or whatever) that does this ?<
Here is an O(n) generic solution for finding the most common element in an iterator range. You use it simply by doing:
int commonest = most_common(my_vector.begin(), my_vector.end());
The value type is extracted from the iterator using iterator_traits<>
.
template<class InputIt, class T = typename std::iterator_traits<InputIt>::value_type>
T most_common(InputIt begin, InputIt end)
{
std::map<T, int> counts;
for (InputIt it = begin; it != end; ++it) {
if (counts.find(*it) != counts.end()) {
++counts[*it];
}
else {
counts[*it] = 1;
}
}
return std::max_element(counts.begin(), counts.end(),
[] (const std::pair<T, int>& pair1, const std::pair<T, int>& pair2) {
return pair1.second < pair2.second;})->first;
}
Try this
int FindMode(vector<int> value)
{
int index = 0;
int highest = 0;
for (unsigned int a = 0; a < value.size(); a++)
{
int count = 1;
int Position = value.at(a);
for (unsigned int b = a + 1; b < value.size(); b++)
{
if (value.at(b) == Position)
{
count++;
}
}
if (count >= index)
{
index = count;
highest = Position;
}
}
return highest;
}
You can use the following code:
vector <int> v;
// add some elements
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(1);
int maxCount = 0, mostElement = *(v.begin());
int sz = v.size(); // to avoid calculating the size every time
for(int i=0; i < sz; i++)
{
int c = count(v.begin(), v.end(), v.at(i));
if(c > maxCount)
{ maxCount = c;
mostElement = v.at(i);
}
}
cout << "the number appeared the most is " << mostElement <<"\n";
cout << "it appered " <<maxCount<<" times";
note: you can use the following for loop to avoid any iterator overflow if the size of the vector can't be held by an integer:
for(auto it= v.begin(); it != v.end(); it++)
{
int c = count(v.begin(), v.end(), *it);
if(c > maxCount)
{ maxCount = c;
mostElement = *it;
}
}
Sort it, then iterate through it and keep a counter that you increment when the current number is the same as the previous number and reset to 0 otherwise. Also keep track of what was the highest value of the counter thus far and what the current number was when that value was reached. This solution is O(n log n)
(because of the sort).
Alternatively you can use a hashmap from int to int (or if you know the numbers are within a limited range, you could just use an array) and iterate over the vector, increasing the_hashmap[current_number]
by 1 for each number. Afterwards iterate through the hashmap to find its largest value (and the key belonging to it). This requires a hashmap datastructure though (unless you can use arrays which will also be faster), which isn't part of STL.
If you want to avoid sorting your vector v
, use a map:
int max = 0;
int most_common = -1;
map<int,int> m;
for (vi = v.begin(); vi != v.end(); vi++) {
m[*vi]++;
if (m[*vi] > max) {
max = m[*vi];
most_common = *vi;
}
}
This requires more memory and has a very similar expected runtime. The memory required should be on the order of a full vector copy, less if there are many duplicate entries.
This is how i did it:
int max=0,mostvalue=a[0];
for(i=0;i<a.size();i++)
{
co = (int)count(a.begin(), a.end(), a[i]);
if(co > max)
{ max = co;
mostvalue = a[i];
}
}
I just don't know how fast it is, i.e. O() ? If someone could calculate it and post it here that would be fine.