【问题标题】:C Simple File integers count program implementation problemsC简单文件整数计数程序实现问题
【发布时间】:2013-11-26 20:13:52
【问题描述】:

我做了这个程序,它在给定的文件中找到特定数字的出现。

这是我的完整程序:

#include <string.h>
#define SIZE 100

int main(void) {
   int count=0;
   char *pch=NULL;
   char line[SIZE];
   char target[SIZE]={"20"};
   FILE *fp=fopen("countNumber.txt","r");
   if(!fp) {
      printf("Error unable to open the file\n");
      return 0;
   }
   while(fgets(line, SIZE, fp)){          //gets each line of the file
      pch=&line[0];                       //sets the pointer address to the first char in line
      while((pch=strstr(pch,target)) != NULL) {  //searches for all occurrences of target in line
         //printf("%s\n",pch++); getchar();
         count++;
      }
   }

   fclose(fp);
   printf("target string %s was found %d times\n",target, count);
   return 0;
}

我的计划:

我正在考虑用这个做一些棘手的事情。 我的方法正确吗?

【问题讨论】:

  • 你的方法听起来很合理......你知道strtol函数吗?你的文件只有数字吗?
  • 不,我不确定那是真的。我会在一分钟内发布我的数字文件。
  • 要大于 90% 的数字,您需要找到“下一个最大的数字”。前 20 个数字占数字的 20/23 = 87%。所以 21 号不大于 90% 的数字——它大于 87% 的数字。这在一定程度上取决于您如何定义事物……我在回答中给出的代码示例采用“下一个数字”,因此与您的示例相比,相差 1。我相信你可以解决这个问题......

标签: c arrays file count percentage


【解决方案1】:

通常的做法是:

  • 读入所有数字并将它们放入一个数组中(这有助于提前知道有多少个数字,以便您可以正确调整数组的大小;否则您必须先计算它们,然后再读入)

  • 按升序排列

  • 要查找第 90 个百分位数,请查找 sortedElement[floor(N * 0.9)] 之后的元素

排序有点高级。有一些简单(易于理解和实现)的算法可以很好地处理小型数据集。一种这样的算法是“冒泡排序”。你从一端开始,比较两个数字。较大的“冒泡”起来,再次比较,继续前进。一圈后,您最大的数字位于顶部。现在重复,从底部开始,但要尽快停止。如果您只需要第 90 个百分位数(而不是完全排序的数组),则只需执行几次(N 次的 1/10) - 因为当您按顺序排列 10% 的最大数字时,这些数字中的最低值是你的答案。

在我看来,根据问题的出色措辞,您可以应对自己编写此代码的挑战;如果你不是,请发表评论!

编辑这里是代码:

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

int main(void) {
  FILE* fp;
  char* chBuf=NULL; // where line will be stored
  int* myArray;
  int ii, jj;
  int lineCount;
  int numCount;
  size_t byteCount; // used for reading in the line

  if((fp = fopen("numbers.txt", "r")) == NULL) {
    printf("Unable to open file\n");
    return -1;
  }

  // got here because file is openened.
  // Let's find out how many lines there are
  lineCount = 0;
  while(getline(&chBuf, &byteCount, fp)>0) lineCount++;
  printf("There are %d lines in the file\n", lineCount);

  // now "rewind" to the beginning, and read one line at a time:
  fseek(fp, 0, SEEK_SET);

  // create space for the numbers:
  myArray = malloc(lineCount * sizeof(int));
  numCount = 0;

  // read numbers in - this time, convert them to integers:
  while(getline(&chBuf, &byteCount, fp) > 0) {
    myArray[numCount] = atoi(chBuf);
    // take this line out - just there to show it is working:
    printf("converted number %d: it is %d\n", numCount, myArray[numCount]);
    numCount++;
  }
  fclose(fp);

  // now we have to sort. Since data was sorted low to high,
  // I will sort high to low just to show it works:

  for(ii = 0; ii < numCount - 1; ii++) {
    for(jj = ii + 1; jj < numCount; jj++) {
      if(myArray[ii] < myArray[jj]) {
        int temp = myArray[ii];
        myArray[ii] = myArray[jj];
        myArray[jj] = temp;
      }
    }
    printf("sorted element %d: %d\n", ii, myArray[ii]);
  }
  // we never "sort" the last number... it bubbled to the end:
  printf("sorted element %d: %d\n", ii, myArray[ii]);

  // now find 10% of the number of elements (rounded down)
  // and we will have the number that is bigger than 90% of the numbers in the file
  int index90 = 0.1 * numCount - 1; // automatically gets truncated;
                                    // offset by 1 since index starts at 0
  printf("The first number bigger than 90%% is element %d: it is %d\n", \
    index90, myArray[index90]);
}

这里有几个“技巧”值得给新手程序员指出:

  1. 检查文件是否打开成功,如果没有则采取措施
  2. 使用getline(实际上是gcc 扩展——我不知道你有没有)来安全地读取一行:它将确保缓冲区中有足够的空间。您的方法对您的文件有效 - 我的方法“通常更安全”。
  3. 使用malloc 为数字数组分配足够的空间
  4. 我对“所有数字”进行排序,尽管我真的只需要对前 10% 进行排序即可解决问题。您可以通过在外部排序循环中更改 ii 的上限来提高性能(对于这种情况)。
  5. 我使用的事实是,将浮点数分配给 int 会在我计算所需数字的索引时自动截断它。

享受吧!

【讨论】:

  • 您好,感谢您的解释。是的,我的主要问题是为此编写代码。
【解决方案2】:

您需要有一种方法来分隔文件中的数字。无论如何,在您的代码中,您可以将 200 作为另一个 20。

关于你的计划,如果你能把所有的号码都记下来,你就必须订购它们。一种方法是使用堆来表示具有有序数据的二叉树。一旦您订购了数据,您就可以获得高出 10% 的数据,然后是最低数据。 O(log n) 中的所有内容,但堆中的文件读取和插入量将为 O(n)。

【讨论】:

    【解决方案3】:

    您需要考虑以下几点: - 您需要做的第一件事是将您从文件中读取的数字转换为整数(请参阅 atoi 函数)。 - 第二,确保分配足够的内存来保存所有数字(100 可能不够) - 确保使用正确的数据类型(int 应该没问题)

    一旦你读取了内存中的所有数字,你就可以对它们做任何你想做的事情:对它们进行排序,找到最小值、最大值..等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-17
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 2021-09-02
      相关资源
      最近更新 更多