在数组中选出重复出现次数最少的数字

Pick out the least recurring number in an array

本文关键字:数字 数组      更新时间:2023-10-16

我需要帮助挑选数组中出现次数最少的元素。我想不出任何健壮的算法,有没有在c++库中定义的函数可以做到这一点?

如果你能想出一个算法,请分享。不一定是代码,而是思想

'定义最少循环' -假设一个数组说a[4]包含2,2,2,44是循环次数最少的元素

为了简洁,使用了一些c++ 14的特性,但很容易适应c++ 11:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
using namespace std;
template <typename I>
auto leastRecurring(I first, I last) {
    unordered_map<iterator_traits<I>::value_type, size_t> counts;
    for_each(first, last, [&counts](auto e) { ++counts[e]; });
    return min_element(begin(counts), end(counts), [](auto x, auto y) { return x.second < y.second; })->first;
}
int main() {
    const int a[] = {2, 2, 2, 3, 3, 4};
    cout << leastRecurring(begin(a), end(a)) << endl;
}

仅使用std goodies (Coliru上的实时演示):

// Your original vector
auto original = { 2, 2, 2, 4, 4 };
// Sort numbers and remove duplicates (in a copy, because std::unique modifies the contents)
std::vector<int> uniques(original);
std::sort(std::begin(uniques), std::end(uniques));
auto end = std::unique(std::begin(uniques), std::end(uniques));
// Count occurences of each number in the original vector
// The key is the number of occurences of a number, the value is the number
std::map<int, int> population;
for (auto i = uniques.begin(); i != end; ++i) {
    population.emplace(std::count(std::begin(original), std::end(original), *i), *i);
}
// The map is sorted by key, therefore the first element is the least recurring
std::cout << population.begin()->second;

请注意,在您给出的示例中,数组已经排序。如果你知道这将永远是这种情况,你可以摆脱对std::sort的调用。

如果两个数字有相同的人口计数,将保留较大的那个。

from collections import Counter
def leastFrequentToken(tokens):
    counted = Counter(tokens)
    leastFrequent = min(counted, key=counted.get)
    return leastFrequent

本质上,创建token:count的映射,在映射中找到最小的值并返回它的键。

假设'number '是int型:

// functor to compare k,v pair on value
typedef std::pair<int, size_t> MyPairType;
struct CompareSecond
{
    bool operator()(const MyPairType& left, const MyPairType& right) const
    {
        return left.second < right.second;
    }
};

vector<int> tokens[4] = { 2, 2, 2, 4 };
map<int, size_t> counted;
for (vector<int>::iterator i=tokens.begin(); i!=tokens.end(); ++i)
{
    ++counted[*i];
}
MyPairType min 
      = *min_element(counted.begin(), counted.end(), CompareSecond());
int leastFrequentValue = min.second;

c++翻译使用这些问题的答案:c++使用std::map计数实例/直方图查找Map中的最小值

在c++ 11中,假设你的类型支持严格的弱排序(对于std::sort),下面可能会有所帮助:https://ideone.com/poxRxV

template <typename IT>
IT least_freq_elem(IT begin, IT end)
{
    std::sort(begin, end);
    IT next = std::find_if(begin, end, [begin](decltype(*begin) el) { return el != *begin; });
    IT best_it = begin;
    std::size_t best_count = next - begin;
    for (IT it = next; it != end; it = next) {
        next = std::find_if(it, end, [it](decltype(*begin) el) { return el != *it; });
        const std::size_t count = next - it;
        if (count < best_count) {
            best_count = count;
            best_it = it;
        }
    }
    return best_it;
}