Find which numbers appears most in a vector

2020-04-06 01:47发布

问题:

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 ?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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;
}


回答5:

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;
}


标签: c++ vector