Режим поиска вектора чисел в C ++ - PullRequest
6 голосов
/ 26 марта 2011

Итак, я пытаюсь создать базовую программу для изучения основ C ++, я генерирую 100 случайных чисел от 0 до 100 и сохраняю их в векторе, затем я отображаю сумму, среднее, медиану, режим , максимум и минимум вектора. У меня все остальное сделано, кроме режима, в котором я застреваю. Вот код, который у меня есть.

int modeFunction()
     {
         numMode = 0;
         count = 0;
         for (int n = 0; n < 100; n++)
         {
             for (int y = 0; y < 100; y++)
             {
                 if (numVector.at(y) == numVector.at(n))
                {
                    numMode = numVector.at(y);
                    count++;
                }
             }

         }
         return numMode;
     }

После этого я застреваю, потому что в моем уме это должно работать, но это не так. Он просто выводит последнее число, обычно 100. Любая помощь будет принята с благодарностью.

Ответы [ 7 ]

8 голосов
/ 26 марта 2011

, поскольку все значения находятся в диапазоне от 0 до 100, вы можете эффективно найти режим с помощью гистограммы:

std::vector<int> histogram(101,0);
for( int i=0; i<100; ++i )
  ++histogram[ numVector[i] ];
return std::max_element( histogram.begin(), histogram.end() ) - histogram.begin();
5 голосов
/ 26 марта 2011

Поскольку режим - это число, которое встречается чаще всего, вы не должны изменять numMode, если только счет нового номера не превышает счет numMode.

РЕДАКТИРОВАТЬ: Для уточнения необходимо сохранитьотдельный счет для текущего элемента и текущего номера, который вы считаете режимом.В идеале, установка newMode на первый элемент - это хороший подход.

Кроме того, режим не обязательно должен быть уникальным (т. Е. «1 1 2 2»).Вы можете иметь это в виду, если вы заботитесь об этом.

newMode = element[0]
modeCount = # of occurrence of newMode

for ( i-th element from [1 to end] ) {
   tmpCount = # of occurrence of element[i]
   if tmpCount > modeCount {
     newMode = element[i]
     modeCount = tmpCount
   }
}
1 голос
/ 26 марта 2011

Подход bmcnett прекрасно работает, если количество элементов достаточно мало. Если у вас есть большое количество элементов, но все значения элементов находятся в небольшом диапазоне, использование map / hashmap работает хорошо. Что-то вроде

typedef std::pair<int, int> mode_pair;

struct mode_predicate
{
  bool operator()(mode_pair const& lhs, mode_pair const& rhs)
  {
    return lhs.second < rhs.second;
  }
};

int modeFunction()
{
  std::map<int, int> mode_map;
  for (int n = 0; n < 100; n++)
    mode_map[numVector[n]]++;
  mode_predicate mp;
  return std::max_element(mode_map.begin(), mode_map.end(), mp)->first;
}
1 голос
/ 26 марта 2011

Альтернативные решения. Примечание: не проверено.

int mode1(const std::vector<int>& values)
{   
    int old_mode = 0;
    int old_count = 0;
    for(size_t n=0; n < values.size(); ++n) 
    {
        int mode = values[n];
        int count = std::count(values.begin()+n+1, values.end(), mode);

        if(count > old_count) 
        {
            old_mode = mode;
            old_count = count;
        }
    }
    return old_mode;
}

int mode2(const std::vector<int>& values)
{   
    return std::max_element(values.begin(), values.end(), [](int value)
    {
        return std::count(values.begin(), values.end(), value);
    });
}
1 голос
/ 26 марта 2011

Ваш алгоритм неверен - он выводит последнее число в массиве, потому что это все, что он может сделать. Каждый раз, когда число в индексе y совпадает с номером в индексе n, вы перезаписываете результаты для предыдущего n. Поскольку вы используете одинаковые условия цикла, y и n равны всегда одинаково по крайней мере в одной точке вложенного цикла для каждого возможного значения n - и вы всегда закончите с numMode, являющимся numVector.at(99).

Вам нужно изменить свой алгоритм, чтобы сохранить счетчик для каждого индекса n на этом пути (или, по крайней мере, какой индекс n закончился с наибольшим count), чтобы вы могли знать в конце цикл n, запись которого происходила чаще всего.

0 голосов
/ 14 июня 2019
    int number = array_list[0];
    int mode = number;
    int count = 1;
    int countMode = 1;

    for (int i=1; i<size_of_list; i++)
    {
          if (array_list[i] == number) 
          { // count occurrences of the current number
             count++;
             if (count > countMode) 
                {
                      countMode = count; // mode is the biggest ocurrences
                      mode = number;
                }
          }
          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_list[i];
      }
    }
0 голосов
/ 26 марта 2011

Режим означает число с самой высокой частотой. Логика должна быть -

//Start of function

int mode = 0, globalCount = 0 ;  
// Start of outer for loop
for i = 0 to length - 1    
   int localCount = 0   

  // Start of inner for loop  
  for j = 0 to length - 1      
     if vec[i] == vec[j]    
     ++localCount    
 // End of Inner for loop 

 if ( localCount > globalCount )  
     globalCount = localCount  
     mode = vec[i]  
// End of outer for loop  

if globalCount > 1 // This should be checked whether vec has repetitions at all
   return mode
else
   return 0

// End of function
...