挑选一个数组中最不重复的数字

时间:2014-03-14 16:11:35

标签: c++ arrays c++11

我需要帮助挑选数组中最不重复的元素。我无法想到任何强大的算法,c ++库中是否定义了这样的函数?

如果您有可以提出的算法,请分享。代码不一定,但想法

'定义最不定期' - 假设数组说a[4]持有2,2,2,44是最不重复的元素

4 个答案:

答案 0 :(得分:2)

为简洁起见,使用了一些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;
}

答案 1 :(得分:1)

仅使用std个好友(live demo on 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的调用。

如果两个数字具有相同的人口数,则将保留更大的数字。

答案 2 :(得分:0)

from collections import Counter

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

基本上,创建一个令牌地图:count,找到地图中的最小值并返回其键。

假设'数字'是整数:

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

使用这些SO问题答案的C ++翻译: C++ counting instances / histogram using std::mapFinding minimum value in a Map

答案 3 :(得分:0)

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