3 Stimmen

C Einfaches Datei-Integers-Zählprogramm Implementierungsprobleme

Ich habe dieses Programm geschrieben, das das Vorkommen einer bestimmten Zahl in einer gegebenen Datei findet.

Hier ist mein komplettes Programm:

#include 
#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("Fehler beim Öffnen der Datei\n");
      return 0;
   }
   while(fgets(line, SIZE, fp)){          //holt jede Zeile der Datei
      pch=&line[0];                       //setzt die Zeigeradresse auf das erste Zeichen in der Zeile
      while((pch=strstr(pch,target)) != NULL) {  //sucht nach allen Vorkommen von target in der Zeile
         //printf("%s\n",pch++); getchar();
         count++;
      }
   }

   fclose(fp);
   printf("Zeilensuche %s wurde %d mal gefunden\n",target, count);
   return 0;
}

Mein Plan:

Ich dachte, ich könnte etwas Trickreiches damit machen. Ist mein Ansatz richtig?

1voto

Floris Punkte 45005

Der übliche Weg, dies zu tun, ist:

  • Lesen Sie alle Zahlen ein und speichern Sie sie in einem Array (es hilft zu wissen, wie viele Zahlen im Voraus vorhanden sind, damit Sie das Array entsprechend dimensionieren können. Andernfalls müssen Sie sie erst zählen und dann einlesen)

  • Sortieren Sie sie in aufsteigender Reihenfolge

  • Um das 90. Perzentil zu finden, suchen Sie das Element, das auf sortedElement[floor(N * 0,9)] folgt

Das Sortieren ist etwas fortgeschritten. Es gibt einfache (leicht verständliche und umsetzbare) Algorithmen, die gut mit kleinen Datensätzen funktionieren. Einer dieser Algorithmen ist der "Bubble Sort". Sie beginnen an einem Ende und vergleichen zwei Zahlen. Die größere "blubbert" hoch, vergleichen erneut, usw. Nach einer Runde steht Ihre größte Zahl oben. Wiederholen Sie dies jetzt, beginnend am unteren Ende, aber um eins früher stoppen. Wenn Sie nur das 90. Perzentil benötigen (anstatt eines vollständig sortierten Arrays), müssen Sie dies nur einige Male tun (1/10 von N-Mal) - denn wenn Sie die 10% größten Zahlen geordnet haben, ist die niedrigste davon Ihre Antwort.

Mir scheint, basierend auf der ausgezeichneten Formulierung der Frage, dass Sie bereit sind, sich der Herausforderung zu stellen und diesen Code selbst zu schreiben. Wenn nicht, hinterlassen Sie einen Kommentar!

EDIT hier ist der Code:

#include 
#include 

int main(void) {
  FILE* fp;
  char* chBuf=NULL; // wo die Zeile gespeichert wird
  int* myArray;
  int ii, jj;
  int lineCount;
  int numCount;
  size_t byteCount; // für das Einlesen der Zeile verwendet

  if((fp = fopen("numbers.txt", "r")) == NULL) {
    printf("Datei kann nicht geöffnet werden\n");
    return -1;
  }

  // bis hierher gekommen, weil die Datei geöffnet ist.
  // Lassen Sie uns herausfinden, wie viele Zeilen es gibt
  lineCount = 0;
  while(getline(&chBuf, &byteCount, fp)>0) lineCount++;
  printf("Es gibt %d Zeilen in der Datei\n", lineCount);

  // jetzt "zurückspulen" zum Anfang und lesen Sie eine Zeile nach der anderen:
  fseek(fp, 0, SEEK_SET);

  // Platz für die Zahlen erstellen:
  myArray = malloc(lineCount * sizeof(int));
  numCount = 0;

  // Zahlen einlesen - dieses Mal in Integer konvertieren:
  while(getline(&chBuf, &byteCount, fp) > 0) {
    myArray[numCount] = atoi(chBuf);
    // diese Zeile entfernen - nur um zu zeigen, dass es funktioniert:
    printf("konvertierte Zahl %d: sie ist %d\n", numCount, myArray[numCount]);
    numCount++;
  }
  fclose(fp);

  // jetzt müssen wir sortieren. Da die Daten von niedrig nach hoch sortiert waren,
  // sortiere ich von hoch nach niedrig, um zu zeigen, dass es funktioniert:

  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("sortiertes Element %d: %d\n", ii, myArray[ii]);
  }
  // wir sortieren die letzte Zahl nie... sie ist ans Ende geblubbert:
  printf("sortiertes Element %d: %d\n", ii, myArray[ii]);

  // jetzt finden Sie 10% der Anzahl der Elemente (abgerundet),
  // und Sie werden die Zahl finden, die größer als 90% der Zahlen in der Datei ist
  int index90 = 0,1 * numCount - 1; // wird automatisch abgeschnitten;
                                    // Offset um 1, da Indizes bei 0 beginnen
  printf("Die erste Zahl größer als 90%% ist Element %d: es ist %d\n", \
    index90, myArray[index90]);
}

Es gibt hier einige "Tricks", die es wert sind, einem Anfängerprogrammierer zu erklären:

  1. Überprüfen Sie, ob die Datei erfolgreich geöffnet wurde, und handeln Sie entsprechend, wenn nicht
  2. Verwenden Sie getline (tatsächlich eine GCC-Erweiterung - ich weiß nicht, ob Sie diese haben), um sicher eine Zeile zu lesen: es stellt sicher, dass genügend Platz im Puffer vorhanden ist. Ihre Methode ist für Ihre Datei gültig - meine ist "generell sicherer".
  3. Verwenden Sie malloc, um genügend Platz für das Array der Zahlen zu reservieren
  4. Ich sortiere "alle Zahlen", auch wenn ich wirklich nur die ersten 10% sortieren muss, um das Problem zu lösen. Sie können die Leistung (in diesem Fall) verbessern, indem Sie das obere Limit von ii in der äußeren Sortierschleife ändern.
  5. Ich nutze die Tatsache, dass eine Gleitkommazahl einer int zugewiesen wird, um automatisch abzuschneiden, bei meiner Berechnung des Index der gesuchten Zahl.

Genießen Sie es!

0voto

rodolk Punkte 5377

Sie müssen eine Möglichkeit haben, die Zahlen in der Datei zu trennen. Jedenfalls könnten Sie 200 in Ihrem Code als weitere 20 nehmen.

Was Ihren Plan betrifft, wenn Sie alle Ihre Zahlen im Speicher speichern können, müssen Sie sie ordnen. Ein Weg ist die Verwendung eines Heaps, um einen binären Baum mit den geordneten Daten darzustellen. Sobald Sie die Daten geordnet haben, können Sie die 10% höheren und davon das Minimum erhalten. Alles in O(log n), außer dem Dateilesevorgang und der Anzahl der Einfügungen in den Heap, die O(n) sein werden.

0voto

Pandrei Punkte 4749

Es gibt ein paar Dinge, die Sie beachten müssen: - das erste, was Sie tun müssen, ist die Zahlen, die Sie aus der Datei lesen, in Ganzzahlen umzuwandeln (bitte beachten Sie die atoi-Funktion dafür). - Zweitens, stellen Sie sicher, dass Sie genügend Speicherplatz zur Verfügung stellen, um alle Ihre Zahlen zu halten (100 könnte nicht ausreichen) - Stellen Sie sicher, dass Sie den richtigen Datentyp verwenden (int sollte in Ordnung sein)

Wenn Sie alle Ihre Zahlen im Speicher gelesen haben, können Sie damit machen, was Sie wollen: sortieren, min, max finden usw.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X