C++ вычисление режима отсортированного массива

Мне нужно написать код 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; 

person John    schedule 12.11.2013    source источник
comment
Вы также можете использовать хэш-карту, если не хотите сортировать. Но я все еще не совсем понимаю, о чем вы пытаетесь спросить. Можем ли мы получить больше информации?   -  person gongzhitaao    schedule 12.11.2013
comment
Прочтите определение режима. Вы хотите найти число, которое повторяется чаще всего. Вы можете отсортировать числа, а затем найти наибольший общий диапазон, или вы можете создать гистограмму и найти элемент с наибольшим числом (@gongzhitaao предлагает хеш-карту). Это будет O(n) времени и O(n) места, что немного лучше, чем сортировка массива.   -  person ChuckCottrill    schedule 12.11.2013
comment
counter это не режим. См. здесь режим   -  person gongzhitaao    schedule 12.11.2013


Ответы (14)


Если массив уже отсортирован, вы можете сразу подсчитать количество вхождений числа. Затем просто сохраните число, которое имеет наибольшее количество вхождений. А узнать режим можно только в одном цикле for. В противном случае вам придется выполнить более одного цикла for. См. подробный пример по ссылке ниже Find-the-Mode -из-набора-чисел

Вот код,

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;
person Deidrei    schedule 12.11.2013
comment
Спасибо, я нашел это полезным, но мне пришлось переключаться между count и countMode внутри блока else, чтобы это работало. - person 1.618; 21.05.2014
comment
счет никогда не увеличивается. - person Don Larynx; 21.01.2015
comment
Есть опечатка, которая приводит к логической ошибке: заменить countMode++ на count++. - person nmgeek; 10.02.2016
comment
Пока работает (за исключением одной опечатки), работает только при наличии одиночного режима. Если имеется более одного режима, вывод не будет отражать это. Любой, кто просматривает этот ответ, должен знать об этом, и, поскольку вы, скорее всего, делаете это для домашнего задания, использование этого решения, вероятно, будет помечено как неправильное выполнение для недопустимого вывода, независимо от того, насколько действительным оно может показаться. Несмотря на запутанность, @ali, похоже, опубликовал наиболее точный способ получения режима в этом посте. - person Turk; 25.01.2017
comment
не работает, если режим является последним числом в массиве. например: интервал [] {1,2,3,4,5,5,6,6,6} - person Parmar Kamlesh; 04.05.2019

Один из способов заключается в том, что вы можете использовать кодирование Run Length. В кодировании Run Length представление будет выглядеть так: (Элемент, его частота).

При этом следите за максимальной частотой и Item. Это даст вам режим, как только вы закончите длину пробега.

Например:

 1 1  2 2 2 3 3 4 5

Кодирование длины цикла будет

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

Ему нужно O(n) места.

person doptimusprime    schedule 12.11.2013

Вот как я это сделал, мое решение будет принимать отсортированный вектор в качестве входных данных. Он имеет временную сложность 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;

}

person Anh Nguyen    schedule 27.03.2018

Вот фрагмент кода:

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;
person Aseem Baranwal    schedule 01.02.2014
comment
не работает, если режим является последним числом в массиве. например: int[] {1,2,3,4,5,5,6,6,6} поставить if (count › countMode) { countMode = count; режим = число;} вне иначе - person Parmar Kamlesh; 04.05.2019

«Мода» — это значение, которое встречается чаще всего. Если число не повторяется, то для списка нет режима. Таким образом, сортировка не принесет пользы, если вам нужно знать «режим».

Вы уверены, что не имеете в виду медиану? Медиана — это среднее число в наборе. Если у вас есть 1, 2, 3, 4, 5, медиана (среднее число) - это (общее_число)/2), округленное в большую сторону, если оно нечетное, 2,5 -> 3, и наша медиана будет равна 3. вы можете только вычислить медиана, если ваши числа отсортированы. Если у вас есть четное число в наборе 1,2,3,4,5,6, ваш режим - слоты 3,4 (по совпадению также, 3,4) (общее_число)/2 слота и (общее_число)/2 + 1 слот , для любого четного массива чисел.

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

person Harlow44    schedule 12.11.2013

Этот код должен дать вам режим. Если имеется равное количество двух разных чисел, он выведет первое из них.

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;
person Mars    schedule 12.11.2013

Этот код находит режим в 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;
}
person ali    schedule 03.08.2016

Я сделал это следующим образом:

    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 в список чисел и посмотреть, что произойдет, если два числа имеют одинаковые значения! Я надеюсь, что это помогает.

person M-J    schedule 10.02.2017

Этот код использует «карту», ​​чтобы узнать РЕЖИМ из данного массива. Предполагается, что массив уже отсортирован.

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;
}
person oya163    schedule 25.02.2017

Это сработало.

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;
person Kolitha Warnakulasooriya    schedule 04.11.2017

Есть старая пословица, которая гласит: «Если вы поместите 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;
}
person Scott A    schedule 25.12.2018

Хотя ответ Дидрея близок, несколько человек указали на некоторые недостатки, например, если режим определяется последними числами отсортированного массива (1,2,3,3,4,4,4 вернет 3 в качестве режима). Кроме того, в зависимости от требований по обработке нескольких режимов будут разные решения.

Это решение делает несколько вещей:

  1. Решает проблему режима, находящегося в конце массива
  2. Если есть несколько режимов (более 1 числа имеет одинаковое количество вхождений с количеством > 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;
person STLxZEROx    schedule 16.07.2019

Я знаю, что вопрос старый, но вот чистый и короткий код, который вычисляет статистический режим:

std::sort(vector.begin(), vector.end());
int mode = vector[0], count = 0, countMode = 1;
for (int i = 1; i < vector.size(); ++i)
{
    if (vector[i] == mode) ++countMode;
    else ++count;
    if (count > countMode)
    {
        mode = vector[i];
        countMode = count;
        count = 0;
    }
}
person juan carlos    schedule 24.03.2021

Это код, который я написал для отсортированного вектора

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;
}
person AUNG    schedule 29.03.2021