0

我正在寻找一种优雅的方法来确定 C++ ptr 数组中哪个元素出现次数最多(模式)。

例如,在

{"pear", "apple", "orange", "apple"}

"apple"元素是最常见的元素。

我以前的尝试失败了编辑:数组已经排序。

int getMode(int *students,int size)
{
    int mode;
    int count=0, 
    maxCount=0,
    preVal;

    preVal=students[0]; //preVall holds current mode number being compared
    count=1;
    for(int i =0; i<size; i++) //Check each number in the array
    {
        if(students[i]==preVal) //checks if current mode is seen again
        {
            count++; //The amount of times current mode number has been seen.
            if(maxCount<count)  //if the amount of times mode has been seen is more than maxcount
            {
                maxCount=count; //the larger it mode that has been seen is now the maxCount
                mode=students[i]; //The current array item will become the mode
            }else{
                preVal = students[i];
                count = 1;
            }

        }

    }

    return mode; 
}
4

1 回答 1

5

这个问题有几种可能的解决方案,但首先是一些建议:不要使用 C 样式的数组。用于std::array固定(编译时)大小的数组或std::vector堆上的数组(或 C++14 std::dynarray,如果数组大小在运行时确定但在创建后不更改)。这些容器为您进行内存管理,您无需单独传递数组大小。除了使用容器之外,更喜欢在合适的<algorithm>地方使用算法。如果您不了解容器和算法,请花一些时间熟悉它们,时间很快就会得到回报。

所以,这里有一些解决方案草图:

  1. 对数组进行排序,然后计算连续值的出现次数。这比跟踪您已经计算过哪些值以及未计算过的值要容易得多。您基本上只需要两个值计数对:一个用于您当前计数的值,一个用于迄今为止的最大计数。您只需要第五个变量:容器的迭代器。

  2. 如果您无法对数组进行排序或需要跟踪所有计数,请使用映射将值映射到它们在数组中的出现次数。如果您熟悉std::map,那很容易做到。最后,搜索最大计数,即最大映射值:

    for (auto i: students) countMap[i]++;
    auto pos = std::max_element(begin(countMap), end(countMap), 
      [](auto lhs, auto rhs){ return lhs.second < rhs.second }); //! see below
    auto maxCount = pos->second;
    

注意:这使用基于 C++11 的范围和 C++14 多态 Lambda。这里所做的事情应该很明显,因此可以针对编译器提供的 C++11/C++14 支持进行调整。

于 2013-05-07T06:22:39.603 回答