3

特定のファイルで特定の数字の出現を見つけるこのプログラムを実行しました。

ここに私の完全なプログラムがあります:

#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;
}

私の計画:

私はこれで何かトリッキーなことを考えていました。私のアプローチは正しいですか?

4

3 に答える 3

1

これを行う通常の方法は次のとおりです。

  • すべての数値を読み取り、それらを配列に入れます (配列のサイズを適切に設定できるように、事前に数値を知っておくと役立ちます。それ以外の場合は、最初に数値を数えてから読み取る必要があります)。

  • それらを昇順に並べ替えます

  • 90 パーセンタイルを見つけるには、sortedElement[floor(N * 0.9)] に続く要素を見つけます

並べ替えは少し高度です。小さなデータセットでうまく機能する単純な (理解して実装するための) アルゴリズムがあります。そのようなアルゴリズムの 1 つが「バブル ソート」です。一方の端から開始し、2 つの数値を比較します。大きい方が「泡立ち」、もう一度比較して、続けます。1周後、あなたの最大の数字が一番上にあります。ここで、一番下から始めて、1 つ早く停止することを繰り返します。(完全にソートされた配列ではなく) 90 パーセンタイルのみが必要な場合は、これを数回 (N 回の 1/10) 行うだけで済みます。あなたの答えです。

質問の優れた言い回しに基づいて、このコードを自分で書くという挑戦に挑戦しているように思えます。そうでない場合は、コメントを残してください。

EDITここにコードがあります:

#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数値のインデックスの計算で自動的に切り捨てられるという事実を使用します。

楽しみ!

于 2013-11-14T01:18:50.160 に答える