显示数字的程序出现(N / 2 + 1)次

时间:2017-10-15 08:40:29

标签: c

我是编程的初学者。我写了一个程序来显示一个数字出现(N / 2 + 1)次。但每次我运行它,我的cmd崩溃。我想也许我的数组有错误。

我的文字文件 - values3.txt的数字为{2, 3, 2, 2, 2, 3, 2, 1}

#include <stdio.h>

#define range_of_nums 3

int main(void)
{   
    int i;
    int num_of_values = 8;
    int a[num_of_values];
    int freq[range_of_nums];
    int current = 0;
    int found_number = 0;

    FILE *fp;

    fp = fopen("values3.txt", "r");

    for (i=0;i<num_of_values;i++)
    {
        fscanf(fp, "%d", &a[i]);
    }

    fclose(fp);

    for (i=0;i<num_of_values;i++)
    {
        current = a[i] - 1;
        freq[current] += 1;
    }

    num_of_values = num_of_values / 2;

    for(i=0;i<range_of_nums;i++)
    {
        if (freq[i] > num_of_values)
        {
            found_number = i+1;
        }
    }

    if (found_number != 0)
    {
        printf("The number %d occurs more than N/2 %d times \n", found_number, num_of_values);
    }

    else 
    {
        printf("No number occurs more than N/2 times\n");
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

你实际上是在正确的道路上,你只是因为未能验证你的文件是否已打开而在最后的循环逻辑中失败了。您还有一个问题,即未验证您实际上是否从文件中获得了num_of_values个值。

让我们首先删除“values3.txt文件在哪里?”问题。 main()提供了传递参数的功能,例如文件名,可以使用它。 main接受论证的声明是:

int main (int argc, char *argv[])  /* where argc arguments are passed in argv */

这消除了程序中values3.txt的硬编码。只需传递文件名作为第一个参数和

FILE *fp = fopen (argv[1], "r");

或者,更好地使用三元运算符在argv[1]中打开文件(如果已给出),否则从stdin读取(默认情况下):< / p>

FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

始终验证您的文件是否已打开以供阅读,如果不是,则处理错误,例如

if (!fp) {  /* validate file open for reading */
    fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
    return 1;
}

您遇到的另一个重要问题是无法将freq初始化为零。当您在代码中启动freq[current] += 1;时,freq[current]必须事先设置为零才能使其有意义。您只需要一个简单的初始化:

    freq[range_of_nums] = {0},      /* you must initialize freq */

关于逻辑问题。您希望将num_of_valuesa整数值的最大读取到8,但不能再读取。再读一次会调用 Undefined Behavior 。无法保证文件中始终存在6个整数。如果26怎么办?如果for (i = 0; i < num_of_values; i++)怎么办?你必须处理所有案件。因此,不要使用num_of_values循环,为什么不只是读取所有值并确保您的读数不超过/* read each value up to num_of_values */ while (i < num_of_values && fscanf (fp, "%d", &a[i]) == 1) i++; ?类似的东西:

6

如果您只阅读if (i != num_of_values) /* validate 8 values read */ num_of_values = i; /* if not adjust number */ 值,怎么能调整?也许:

fscanf

注意>您已经知道N/2前面的测试不能更多

你不一定要改变你的变量,保持你的数组中的元素数量(保持这一点很重要)。为什么我们不使用新变量来保留num_by_2(比如num_by_2 = num_of_values / 2; /* you need another var */ 。然后你可以这样做:

num_of_values

,同时仍保留N/2,以便稍后在您的代码中使用。

最后,如果我理解正确,您需要识别出现时间超过N/2的所有数字。循环布局中存在逻辑问题。要查找大于printf次的所有值,for (i = 0; i < range_of_nums; i++) { if (freq[i] > num_by_2) { found_number = i + 1; printf ("The number %d occurs more than N/2 %d times \n", found_number, num_by_2); } } 必须位于该循环中,例如

found_number

现在您知道if (found_number == 0) printf("No number occurs more than N/2 times\n"); 是否有值,是否找到了值。所以你的最后一次测试可能只是:

#include <stdio.h>

#define range_of_nums 3

int main (int argc, char **argv)
{   
    int i = 0,
        num_of_values = 8,              /* you have 8 values */
        a[num_of_values],               /* otherwise your VLA is wrong */
        freq[range_of_nums] = {0},      /* you must initialize freq */
        num_by_2 = 0,
        found_number = 0;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* read each value up to num_of_values */
    while (i < num_of_values && fscanf (fp, "%d", &a[i]) == 1)
        i++;

    if (fp != stdin) fclose (fp);       /* close file if not stdin */

    if (i != num_of_values)             /* validate 8 values read */
        num_of_values = i;              /* if not adjust number   */

    for (i = 0; i < num_of_values; i++) /* set frequency array vals */
        freq[a[i] - 1] += 1;

    num_by_2 = num_of_values / 2;       /* you need another var */

    for (i = 0; i < range_of_nums; i++)
    {
        if (freq[i] > num_by_2)
        {
            found_number = i + 1;
            printf ("The number %d occurs more than N/2 %d times \n",
                    found_number, num_by_2);
        }
    }

    if (found_number == 0) 
        printf("No number occurs more than N/2 times\n");

    return 0;
}

完全放弃,您可以使用类似于以下内容的方式清理逻辑:

$ echo "2 3 2 2 2 3 2 1" | ./bin/numby2freq
The number 2 occurs more than N/2 4 times

示例使用/输出

<div *ngFor="let client_obj of dashboard_data.data.items ;let i = index"    >
      <input type="checkbox"   [(ngModel)]="div_['level_1_'+i]">
          <div [class.hide]="div_['level_1_'+i]"   >
             {{client_obj.value}}
        </div>
 </div>

仔细看看,如果您有其他问题,请告诉我。

答案 1 :(得分:0)

此错误列表可能不完整。

fp = fopen("values3.txt", "r");

您不会查看您的文件是否已打开

fp = fopen("values3.txt", "r");
if (fp == NULL) {
  perror("fopen()");
  return 1;
}
fscanf(fp, "%d", &a[i]);

您无法验证fscanf是否成功

int ret = fscanf(fp, "%d", &a[i]);
if (ret != 1) {
  fprintf(stderr, "error input");
  return 1;
}
current = a[i] - 1;
freq[current] += 1;

您信任用户输入,索引可能超出范围

current = a[i] - 1;
if (current < 0 || curent >= 8) {
  fprintf(stderr, "error range");
  return 1;
}
freq[current] += 1;