2013-05-07 101 views
0

我正在寻找一种确定哪个元素在C++ ptr数组中具有最高出现(模式)的优雅方法。C++寻找在数组中发生率最高的元素

例如,在

{"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; 
} 
+0

排序数组是一个选项?治疗将更加简单/快速。 – MisterJ 2013-05-07 06:18:03

+0

哦,忘了提及它已经排序。 – 2013-05-07 06:19:34

+0

哼...所以你的数组看起来像'['苹果','苹果','橙','梨']'? – MisterJ 2013-05-07 06:20:56

回答

4

有该问题的几种可能的解决方案,但首先一些建议: 不要使用C风格的数组。对于固定(编译时)大小的数组,使用std::array;对于堆上的数组,则使用std::array;如果数组大小在运行时确定,但在创建后不更改,则使用C++ 14的std::dynarray。这些容器为您执行内存管理,并且不需要单独传递数组大小。除了使用容器之外,更喜欢使用<algorithm>中适用的算法。如果你不知道容器和算法,花一些时间去熟悉它们,这段时间很快就会得到回报。

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

  1. 排序数组,然后计算连续值的ocurrences。跟踪哪些数值已经计算,哪些不计算,要容易得多。您基本上只需要两个值计数对:一个用于您当前正在计数的值,一个用于至今为止的最大值。你只需要第五个变量:容器的迭代器。

  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支持进行调整。