10

我必须编写一个 C++ 代码来查找数组的中位数和众数。有人告诉我,在对数字进行排序后,查找数组的模式要容易得多。我对功能进行了排序,但仍然找不到模式。

 int counter = 0;
    for (int pass = 0; pass < size - 1; pass++)
        for (int count = pass + 1; count < size; count++) {
            if (array [count] == array [pass])
                counter++;
            cout << "The mode is: " << counter << endl; 
4

17 回答 17

7

如果数组已经排序,您可以一次计算一个数字的出现次数。然后只保存出现次数最多的数字。而且你只能在一个 for 循环中找出模式。否则,您将不得不执行多个 for 循环。请参阅以下链接中的详细信息示例 Find-the-Mode-of-a-Set-of-Numbers

这是代码,

int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;

for (int i=1; i<size; i++)
{
      if (array[i] == number) 
      { // count occurrences of the current number
         ++count;
      }
      else
      { // now this is a different number
            if (count > countMode) 
            {
                  countMode = count; // mode is the biggest ocurrences
                  mode = number;
            }
           count = 1; // reset count for the new number
           number = array[i];
  }
}

cout << "mode : " << mode << endl;
于 2013-11-12T04:08:17.617 回答
2

一种方法是您可以使用运行长度编码。在运行长度编码中,表示将是这样的;(项目,它的频率)。

这样做时,请跟踪最大频率和项目。完成运行长度后,这将为您提供模式。

例如:

 1 1  2 2 2 3 3 4 5

它的运行长度编码将是

 {1, 2}, {2, 3}, {3, 2}, {4, 1}, {5, 1}

它需要 O(n) 空间。

于 2013-11-12T04:07:58.373 回答
1

这是代码片段:

int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;

for (int i=1; i<size; i++)
{
    if (array[i] == number) 
    {
        count++;
    }
    else
    {
        if (count > countMode) 
        {
            countMode = count;
            mode = number;
        }
        count = 1;
        number = array[i];
    }
}

cout << "mode : " << mode << endl;
于 2014-02-01T10:11:48.010 回答
1
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;

for (int i=1; i<size; i++)
{
  if (array[i] == number) 
  { // count occurrences of the current number
     ++count;
  }
  else
  { // now this is a different number

       count = 1; // reset count for the new number
       number = array[i];
  }
  if (count > countMode) {
              countMode = count;
              mode = number;
  }
}

cout << "mode : " << mode << endl;
于 2019-05-04T14:20:16.393 回答
1

我就是这样做的,我的解决方案将一个排序的向量作为输入。它具有 O(n) 时间复杂度,并且可以处理向量中有超过 1 个“模式”数的情况。

void findMode(vector<double> data) {

double biggestMode = 1;
vector<double> mode, numbers;
numbers.push_back(data.at(0));
mode.push_back(1);
int count = 0;
for (int i = 1; i < data.size(); i++) {
    if (data.at(i) == numbers.at(count)) {
        mode.at(count)++;
    }
    else {
        if (biggestMode < mode.at(count)) {
            biggestMode = mode.at(count);
        }
        count++;
        mode.push_back(1);
        numbers.push_back(data.at(i));
    }
}

for (int i = 0; i < mode.size(); i++) {
    if (mode.at(i) == biggestMode)
        cout << numbers.at(i) << " ";
}
cout << endl;

}

于 2018-03-27T05:15:43.643 回答
1

我知道这个问题很老了,但这是一个计算统计模式的简洁代码:

std::sort(vector.begin(), vector.end());
int mode = vector[0], count = 0, countMode = 1;
int last = mode;
for (int i = 1; i < vector.size(); ++i)
{
    if (vector[i] == mode) ++countMode;
    else
    {
      if (last != vector[i]) count = 0;
      ++count;
    }
    if (count > countMode)
    {
        mode = vector[i];
        countMode = count;
        count = 0;
    }
    last = vector[i];
}
于 2021-03-24T12:26:14.253 回答
1

有一句古老的格言说“如果你把 10 个程序员放在一个房间里,给他们同样的程序来编写代码,你会得到 12 个不同的结果”,因此我回答了你的问题。它可能没有那么快(我计划测试它的速度与其他一些建议),但我觉得它很容易理解。

#include <iostream>

using namespace std;

int main ()
{
    short z[10];
    short maxCount = 0, curCount = 0, cur = 0, most = 0;

    for (int i = 0; i < 10; i++)
        {
         cout << "Enter a number: " << endl;
         cin >> z[i];
        }

    for (int i = 0; i < 10; i++)
        {
         cur = z[i];
            for (int a = i; a < 10; a++)
                {
                 if (cur == z[a])
                    {
                     curCount++;
                     cur = z[a];
                    }
                if (curCount > maxCount)
                   {
                    maxCount = curCount;
                    most = z[a];
                   }
            }
            curCount = 0;
        }

    cout << "the mode is : " << maxCount << ", the number is: " << most << endl;
}
于 2018-12-25T15:31:54.303 回答
0

此代码应该为您提供模式。如果两个不同数字的数量相等,它将输出第一个。

int count = 1, mode = 0, m = 0, i = 1;
size_t sz = sizeof(array)/sizeof(*array);
while(i != sz+1) {
    if(array[i-1] != array[i]) {
        if(count > m) {
            mode = array[i-1];
            m = count;
            count = 1;
        }
    }
    else
        ++count;
    ++i;
}
std::cout << "mode: " << mode << std::endl;
于 2013-11-12T04:22:05.880 回答
0

“模式”是最常出现的值。如果没有数字重复,则列表没有模式。因此,如果您需要知道“模式”,那么排序将没有任何好处。

你确定你指的不是中位数吗?中位数是一组中的中间数。如果您有 1,2,3,4,5,则中位数(中间数)是 (total_number)/2) 如果奇数,则四舍五入,2.5 -> 3,我们的中位数为 3。您只能真正计算如果您的数字已排序,则为中位数。如果您在一组 1,2,3,4,5,6 中有偶数,则您的模式是插槽 3,4(巧合的是,3,4)(total_number)/2 个插槽和(total_number)/2 + 1 个插槽, 对于任何偶数数组。

http://www.purplemath.com/modules/meanmode.htm

于 2013-11-12T04:05:22.863 回答
0

此代码在 C++ 中找到模式:

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    int i,j,k=0,n,repeat_max=0,cn=0;
    int array1[50],mode[50],count[50]={0},c[50];

    cout<<"\n inter count:\t";
    cin>>n; 


    cout<<"\n";

    for(i=0;i<n;i++)
    cin>>array1[i];

    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {

            if(array1[i]==array1[j])
            {   
                count[i]++;
                if(count[i]>=repeat_max)
                {
                    repeat_max=count[i];
                    mode[k++]=array1[i];        
                }
            }
        }
    }
    cout<<"\n================\n";
    for(i=1;i<k;i++)
    cout<<"\t mode[i]="<<mode[i]<<"\n";
    cout<<"\t\n\nrepeat array:"<<repeat_max;

    return 0;
}
于 2016-08-03T16:39:25.650 回答
0

这是我为排序向量编写的代码

void print_mode(vector<int>& input)
{

int mode=0, count = 0;
int current_number = input[0];
int mode_number = current_number;

for (int i=0; i < input.size(); i++)
{
    if (current_number == input[i])//check if the number is the same
    {
        count++;
    }

    else //this fuction works when the value are no longer the same and 
         //this is when it updates the mode value
        {

        if (count > mode)//update mode value
        {
            mode = count;
            mode_number = current_number;
            
        }

        count = 1;// it is not reset back to zero because when it the program detect a 
                  //different number it doesn't count it so this is to solve that issue

    }
    if (i == input.size() - 1)// this function before it doesn't work when the largest value 
                               //is mode so I added this if state to solve it
    {

        if (count > mode)
        {
            mode = count;
            mode_number = current_number;
        }

    }

    current_number = input[i];//prepare for next value
}
cout << mode_number << " is the mode number and it is repeated " << mode << " times" << endl;
}
于 2021-03-29T10:58:11.183 回答
0

此代码使用“map”从给定数组中找出 MODE。它假定数组已经排序。

int findMode(int * arr, int arraySize)
{
    map<int, int> modeMap;
    for (int i = 0; i < arraySize; ++i) {
        ++modeMap[arr[i]];
    }

    auto x = std::max_element(modeMap.begin(), modeMap.end(),
        [](const pair<int, int>& a, const pair<int, int>& b) {
        return a.second < b.second; });

    return x->first;
}
于 2017-02-25T19:26:18.953 回答
0

虽然 Diedrei 的答案很接近,但有几个人指出了一些缺点,例如模式是否由排序数组的最后一个数字定义(1,2,3,3,4,4,4将返回 3 作为模式)。此外,根据如何处理多种模式的要求,会有不同的解决方案。

这个解决方案做了几件事:

  1. 解决模式在数组末尾的问题
  2. 如果有多种模式(超过 1 个数字具有相同的出现次数且 count > 1),则返回最小的数字作为模式
  3. -1如果没有模式则返回(每个数字只出现一次)
int number = array[0];
int mode = number;
int count = 1;
int countMode = 1;

for (int i=1; i<size; i++)
{
      if (array[i] == number) 
      { // increment the count of occurrences for the current number
         ++count;
         if (count > countMode) 
         {
               countMode = count; // this number now has the most occurrences 
               mode = number; // this number is now the mode
         }
      }
      else
      { // now this is a different number
           count = 1; // reset count for the new number
           number = array[i]; // set the new number
  }
}
if (countMode == 1) {
  mode = -1; // set the mode to -1 if each number in the array occur only once
}

cout << "mode : " << mode << endl;
于 2019-07-16T23:02:51.917 回答
0

我是这样做的:

    int main()
{ 
    int mode,modecount2,modecount1;
    bool is_nomode=false;
    vector<int> numbers = { 15,43,25,25,25,25,16,14,93,93,58,14,55,55,55,64,14,43,14,25,15,56,78,13,15,29,14,14,16 };
    sort(numbers);

    //If you uncomment the following part, you can see the sorted list of above numbers
    //for (int i = 0; i < numbers.size(); ++i) std::cout << numbers[i] << '\n';
    //keep_window_open();

    mode = numbers[0];
    modecount1 = 0;
    modecount2 = 1; //Obviously any number exists at least once!
    for (int i = 1; i < numbers.size(); ++i) {
        if(numbers[i]==numbers[i-1]) ++modecount2;
        else {
            if (modecount2 > modecount1) {
                mode = numbers[i - 1];
                modecount1 = modecount2;
            }
            else if (i != 1 && modecount2 == modecount1) { std::cout << "No mode!\n"; is_nomode = true; break; }
            modecount2 = 1;
        }
    }
    if(!is_nomode) std::cout << "Mode of these numbers is: " << mode << std::endl;
    keep_window_open();

您也可以在数字列表中添加另外 25 个,看看如果两个数字出现相同的情况会发生什么!我希望它有所帮助。

于 2017-02-10T15:54:23.860 回答
0

1.不排序找模式

有人告诉我,在对数字进行排序后,查找数组的模式要容易得多

我不确定。

std::vector<std::pair<int, unsigned>> mode(const std::vector<int> &v)
{
  if (v.empty())
    return {};

  std::unordered_set<int> seen;

  unsigned max_count(0);
  std::vector<std::pair<int, unsigned>> ret;

  for (auto i(v.begin()); i != v.end(); ++i)
    if (seen.find(*i) == seen.end())
    {
      const auto count(std::count(i, v.end(), *i));

      if (count > max_count)
      {
        max_count = count;
        ret = {{*i, max_count}};
      }
      else if (count == max_count)
        ret.emplace_back(*i, max_count);

      seen.insert(*i);
    }

  return ret;
}

算法

  • 使用哈希表 ( seen) 跳过已经看到的数字;
  • 不需要输入向量的副本;
  • 只需要一个支持前向迭代器的容器。

另请注意,对于较小的输入向量,该函数可以简化为删除哈希表。

你可以在这里玩代码。

2.寻找模式排序

std::vector<std::pair<int, unsigned>> mode(std::vector<int> v)
{
  if (v.empty())
    return {};

  std::sort(v.begin(), v.end());

  auto current(*v.begin());
  unsigned count(1), max_count(1);

  std::vector<std::pair<int, unsigned>> ret({{current, 1}});

  for (auto i(std::next(v.begin())); i != v.end(); ++i)
  {
    if (*i == current)
      ++count;
    else
    {
      count = 1;
      current = *i;
    }

    if (count > max_count)
    {
      max_count = count;
      ret = {{current, max_count}};
    }
    else if (count == max_count)
      ret.emplace_back(current, max_count);
  }

  return ret;
}

我们假设一个未排序的输入向量,因此该函数适用于已排序和处理的原始向量的副本。

如果原始向量已经排序,则可以通过引用传递输入参数并且std::sort可以删除调用。

你可以在这里玩代码。

表现

性能取决于多个因素(输入向量的大小、值的分布......)。

例如,如果输入整数的范围很小,算法 1算法 2快。

你可以在这里做实验。

于 2022-01-20T08:54:41.597 回答
-1
int findModa(int *arr, int n) {
    int count=1;
    int countmax=0;
    int current = arr[0];
    int moda = 0;
    for (int i=1; i<n; i++) {
        if(arr[i] == curr) {
            count++;
        }
        else if (count>countmax) {
            countmax=count;
            count=1;
            moda=arr[i-1];
            current=arr[i];
        }
        current=arr[i];
    }
    return moda;
}
于 2020-05-10T22:35:00.367 回答
-1

这已经奏效了。

int vals[9];                
sort(vals, vals + 9);
int key = vals[0], value = 1,max_key=0,max_value=0;

for (int l = 1; l < 9; l++){
    if (key == vals[l]){
        value++;
    }
    else{
        if (value>max_value){
            max_key = vals[l-1];
            max_value = value;
        }
        key = vals[l];
        value = 1;
    }
}
cout<< "Mode: "<< max_key << endl;
于 2017-11-04T05:49:04.630 回答