Режим расчета в C - математика немного ошибочна

3-й день программирования на C, так что терпите меня. Я делаю упражнение для начинающих, в котором я генерирую случайные числа и вычисляю среднее значение, стандартное отклонение, медиану и режим.

Проблемы в режиме. Я перехожу к работе над некоторыми другими проектами, но пока я публикую это, чтобы узнать, сможет ли кто-нибудь заметить мою ошибку. Пользователь вводит в начале диапазон случайных чисел и их количество. Режим возвращает правильное значение, если минимум равен 1, но не, если минимум больше.

Также будет интересно, если есть какие-то идеи о том, как разрешить более одного режима - у меня есть приблизительная идея, как это сделать (дополнительный цикл и дополнительный массив?), Но я не совсем уверен, как бы я справился только с печатью. соответствующие значения из нового массива).

Вот (только соответствующие части) мой код:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main() {

    // setting parameters 
    int SIZE, MIN, MAX;
    printf("How low should the smallest random number be?\n");
    scanf("%d",&MIN);
    printf("How high should the largest random number be?\n");
    scanf("%d",&MAX);
    printf("How many random numbers do you want?\n");
    scanf("%d",&SIZE);

    int rnx[SIZE]; 
    int biggles, *tally, count=0;
    int mode;
    int i,j;
    float mean, sumdev, median;

    tally = (int*) calloc (MAX-MIN,sizeof(int)); // creates an array for the tally in the mode function and initializes it to zero for the incrementing.

    srand(time(NULL)); // random seed outside the loop

  // generate random numbers into an array

  for(i=0;i<SIZE;i++) {
    rnx[i]=round(((double)rand()/(RAND_MAX)*(MAX-MIN)+MIN));
  }

  BubbleSort(rnx,SIZE); //  left out for brevity the actual function I wrote for this but it works

  // calculates the mode

  for(i=MIN;i<MAX;i++) {
      for(j=0;j<SIZE;j++) {
          if(rnx[j]==i) {
              tally[i-MIN]++; // in the second array we register how many times each number occurs in the random sequence, checking from the minimum to maximum.
          }
      }
  }
  mode = biggles;
  // for (j=0;j<10;j++) {
  for(i=MIN;i<MAX;i++) {
      if(tally[i-MIN]>count) {
          count=tally[i-MIN];
          if(count>1) {
              mode=i-MIN+1; }
      }
  } 

  if (mode!=biggles) {
    printf("The mode of the random numbers is %d\n",mode); }
  else { printf("The random numbers have no mode.\n"); } // in case there is no mode. but what if there is more than one?
  free(tally);
  return 0;

}

1 ответ

Когда вы делаете это:

tally = (int*) calloc (MAX-MIN,sizeof(int));

Скажем, MAX равен 4, MIN равен 1. Это означает, что вы можете получить 1, 2, 3 и 4 в качестве случайных чисел. Но MAX - MIN = 3, поэтому вы выделяете место только для 3. Измените это на MAX-MIN+1.

Следующая проблема - эта строка.

round(((double)rand()/(RAND_MAX)*(MAX-MIN)+MIN));

Снова скажем, что MAX равен 4, MIN равен 1. Это даст значения где угодно от 1 (round(0*(4-1)+1)) до 4 (round(1*(4-1)+1)) правильно. Тем не менее, от 1 до 1,5 станет 1, тогда как от 1,5 до 2,5 станет 2, аналогично только от 3,5 до 4 станет 4. Таким образом, 1 и 4 в два раза меньше, чем другие числа.

Чтобы решить эту проблему, попробуйте это вместо

floor(((double)rand()/(RAND_MAX+1)*(1+MAX-MIN)+MIN));

Это будет варьироваться от 1 до 4, но даст всем возможностям равные возможности. (Часть RAND_MAX+1 должна убедиться, что она не генерирует 5 с очень малой вероятностью)

Вот как я бы рассчитал режим (не проверено):

for (i = 0; i < SIZE; ++i)
{
    tally[rnx[i]-MIN] += 1;
}

int modecount = 0;
int mode = -1;
for (i = 0; i <= MAX-MIN; ++i) //<= instead of < because MAX is inclusive, not exclusive
{
    if (tally[i] > modecount)
    {
        mode = i+MIN;
        modecount = tally[i];
    }
}

В псевдокоде:

1) Создайте массив, подсчитав, с каким количеством случайных чисел было это число в каждом индексе.

2) Найдите самую большую запись в подсчете и запишите ее положение и посчитайте.

Затем для обработки нескольких режимов:

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

Другие вопросы по тегам