用C计算模式 - 数学有点不对劲

时间:2013-05-31 08:36:55

标签: c mode

C编程的第3天所以请耐心等待。我正在做一个初学者的练习,我在其中生成随机数并计算平均值,std dev。,中位数和模式。

模式中的问题。我正在继续研究其他一些项目,但与此同时我发布这个以查看是否有人能发现我的错误。用户在开始时输入随机数的范围和它们的数量。如果最小值为1,则模式返回正确的值,但如果最小值较大,则返回正确的值。

如果对如何允许多种模式有任何见解也会很有趣 - 我已经大致了解如何做到这一点(一个额外的for循环和一个额外的数组?但不太确定我是怎么做的只处理打印新数组中的相关值。

这是我的代码的唯一部分:

#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 个答案:

答案 0 :(得分:3)

执行此操作时:

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,查找与您为模式找到的最高计数相同的每个条目。所有这些都是模式,如果您不想分配另一个数组来存储它们,您可以在找到它们时将它们打印出来。