【问题标题】:C program returning 0 instead of max occurring integer from sequence of integer inputC程序从整数输入序列返回0而不是最大出现的整数
【发布时间】:2016-02-07 05:39:20
【问题描述】:

我之前发布过关于我的 C 程序中的运行时错误,但现在我遇到了另一个代码问题。我的程序运行良好,没有任何错误,但无论输入什么,它总是打印 0。我花了过去 4 个小时试图弄清楚为什么我的代码会这样做,但我没有运气。如果有人能帮帮我,我将不胜感激。

我的程序接受一个整数序列的输入,使用另一个类似 scanf 的程序。 Getint() 读取整数序列的输入,并在达到 EOF (-1) 时停止读取输入。序列中的整数个数为 1000。

// ar_max(a[]) returns the max entry of a
int ar_max(int a[]) {
  int max_so_far = a[0];
  for (int i = 1; i < 1000; i++) {
    if (a[i] > max_so_far) {
      max_so_far = a[i];
    }
  }
  return max_so_far;
}

int main() {
  int inputnum = getint();
  // array containing the distinct numbers seen
  int a_num[1000] = {};
  // array containing the frequencies of the distinct numbers seen
  int a_freq[1000] = {};
  int len_n = 0;
  while (inputnum != EOF) {
    int i = 0;
    len_n = i + 1;
    int len_f = len_n;
    // update the frequency of inputnum if it's already been seen
    for (i = 0; i < len_f; i++, len_n += 1) {
      if (a_num[i] == inputnum) {
        a_freq[i] = a_freq[i] + 1;
      }
    }
    // add inputnum into the array if it hasn't already been seen
    if (i == len_n) {
      a_num[i+1] = inputnum;
      a_freq[i+1] = 1;
    }
    inputnum = getint();
  }
  // print the first number with the highest frequency
  for (int j = 0; j < len_n; j++) {
    if (a_freq[j] == ar_max(a_freq)) {
      printf("%d\n", a_num[j]);
      break;
    }
  }
}

例如,输入 10 20 30 20 应该是20

【问题讨论】:

  • 尝试在调试器中运行并逐行执行代码。从正常输入集执行此操作有点耗时,因此请使用较小的输入集进行调试。
  • 请发布完整的代码,以便我们重现您的错误。我们不知道函数 getint() 做了什么
  • 我只提供了getint()的接口,没有提供实现
  • 我不知道如何在调试器中运行它
  • 先了解如何调试。 google 上有很多教程。并将代码放在反引号内(与 ~ 相同的键)like this 使其可读

标签: c arrays loops printf user-input


【解决方案1】:
int main() 
{
  // array containing the distinct numbers seen
  int a_num[1000] = {0};
  // array containing the frequencies of the distinct numbers seen
  int a_freq[1000] = {0};
  int len_n = 0;
  int i = 0, j = 0;

  // Read first entry
  int inputnum = getint();
  if (EOF == inputnum)
  {
      printf("No valid number input given\n");
      return -1;
  }

  // Make first entry in a_num and a_freq
  a_num[0] = inputnum;
  a_freq[0] = 1;
  // Update len_n to 1
  len_n = 1;

  // Get new entry from user and update number array and frequency array
  inputnum = getint();
  while (inputnum != EOF) 
  {
      // update the frequency of inputnum if it's already been seen
      for (i = 0; i < len_n; i++) 
      {
          if (a_num[i] == inputnum) 
          {
              a_freq[i] = a_freq[i] + 1;
              break;
          }
      }

      // add inputnum into the array if it hasn't already been seen
      if (i == len_n) 
      {
          a_num[i] = inputnum;
          a_freq[i] = 1;

          // Update len_n
          len_n++;
      }

      // Check if we have already reached 1000
      if (1000 == len_n)
      {
          printf("Reached 1000 entry read\n");
          break;
      }

      // Next entry
      inputnum = getint();
  }

  // print the number with the highest frequency
  int max_freq = ar_max(a_freq);
  for (j = 0; j < len_n; j++) 
  {
      if (a_freq[j] == max_freq) 
      {
          printf("%d\n", a_num[j]);
          break;
      }
  }
}

注意:
1. #define MAX_SIZE 1000 可以使用,因为硬编码值 1000 在代码中重复使用。当您使用新尺寸(例如 1500)并且您只需要更改 #define MAX_SIZE 1500 时,这将有所帮助,其他代码保持不变。
2. ar_max() 函数可以修改为给出max出现的数组索引,以避免main中的for循环查找数组索引。例如

int ar_max(int a[])
{
  int index = 0;
  int max_so_far = a[0];
  for (int i = 1; i < 1000; i++) {
    if (a[i] > max_so_far) {
      max_so_far = a[i];
      index = i;
    }
  }
  return index;
}

在 main() 中:

printf("%d\n", a_num[ar_max(a_freq)]);

【讨论】:

    【解决方案2】:

    代码思路不错,但还是有一些问题。

    首先,您有两个包含相关信息的数组。您为这些数组中的每一个保留两个长度并尝试保持长度相同。这很复杂。相反,请考虑为两个数组设置一个长度。

    当您遍历数组以检查给定数字是否已包含在数组中时:

    for (i = 0; i < len_f; i++, len_n += 1) {
      if (a_num[i] == inputnum) {
        a_freq[i] = a_freq[i] + 1;
      }
    }
    

    您会在每次迭代时更新数字数组的长度。您不应该这样做,因为在循环中迭代时您不会更改任何内容的长度。

    接下来,您检查是否找不到号码:

    if (i == len_n) ...
    

    这不起作用,因为您在第一个循环中更新了频率,但不要终止循环;你的条件永远是真实的。当您找到号码时,您可以通过使用break 显式跳出循环来解决此问题。 (更好的是,让查找和频率更新一个函数,其返回值指示是否找到了元素,如果没有,则添加元素。)

    当你追加新元素时:

    if (i == len_n) {
      a_num[i+1] = inputnum;
      a_freq[i+1] = 1;
    }
    

    当然,您应该增加附加到的数组的长度。一般来说,将一个项目附加到一个数组看起来像这样:

    array[len++] = item;
    

    回想一下,第一个索引为零,实际长度超出有效索引。

    还有其他几点:

    • 添加元素时,应确保不会溢出数组。 1000的维度是慷慨的,但不是无限的。

    • 在您的函数 ar_max 中,您遍历数组的所有 1000 个元素。您已将数组初始化为零,因此最大值仍然是正确的,但最好也将数组大小传递给函数,这样您就可以只迭代实际项目。

    • 1234563 .
    • 如果您有两个并行数组,最好创建一个结构来保存项目和频率并始终将它们保持在一起。这简化了代码,因为您不必保持任何同步。这样的数据布局还有助于对其他常见操作进行排序和过滤。

    这是实现上述修复的版本。它还使用函数按值查找元素,并使ar_max 返回数组索引而不是值。

    #include <stdlib.h>
    #include <stdio.h>
    
    #define MAX 1000
    
    int getint()
    {
        int x;
    
        if (scanf("%d", &x) < 1) return EOF;
        return x;
    }
    
    int ar_max(const int a[], int len)
    {
        if (len == 0) return -1;
    
        int max_so_far = a[0];
        int max_index = 0;
    
        for (int i = 1; i < len; i++) {
            if (a[i] > max_so_far) {
                max_so_far = a[i];
                max_index = i;
            }
        }
    
        return max_index;
    }
    
    int ar_find(const int a[], int len, int which)
    {
        for (int i = 0; i < len; i++) {
            if (a[i] == which) return i;
        }
    
        return -1;
    }
    
    int main()
    {
        int inputnum = getint();
    
        int a_num[MAX] = { };       // distinct numbers seen  
        int a_freq[MAX] = { };      // frequencies of the distinct numbers
        int len = 0;                // actual length of both arrays
    
        while (inputnum != EOF) {
            int i = ar_find(a_num, len, inputnum);
    
            if (i < 0) {            // append new item
                if (len >= MAX) {
                    fprintf(stderr, "Array size %d exceeded\n", MAX);
                    exit(1);
                }
                a_num[len] = inputnum;
                a_freq[len] = 1;
                len++;
            } else {                // increment existing item
                a_freq[i]++;
            }
    
            inputnum = getint();
        }
    
        int imax = ar_max(a_freq, len);
        if (imax >= 0) {
            printf("%d (%d times)\n", a_num[imax], a_freq[imax]);
        } else {
            puts("Empty input.");
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      • 2014-08-25
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多