Vorkommen von Wort in String zählen

Schnelle objektorientierte, kompilierende Programmiersprache.
tauberheli
Beiträge: 16
Registriert: Di Apr 27, 2010 3:47 pm

Re: worin liegt der fehler?

Beitrag von tauberheli » Sa Sep 04, 2010 1:08 pm

Ihr müsst langsam Tacheles mit mir reden.

Ich komm nämlich von selbst nicht drauf. :oops:

LG

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: worin liegt der fehler?

Beitrag von nufan » Sa Sep 04, 2010 1:19 pm

Ok, dann fangen wir ganz von vorne an :)
Wie du wahrscheinlich weißt wird ein String (genauer gesagt ein char-Array) in C durch das Zeichen \0 beendet. Du kennst zwar nicht die Anzahl der Zeichen im Array, aber du weißt wo der String aufhört (so kannst du aber wenn du willst auch die Anzahl bestimmen).
So, was macht dein Programm nun? Du liest die erste Zeile, in deinem Array steht folgendes:
Doch im Semifinale von Roland Garros verliert Melzer schließlich.\0
Was dahinter steht ist Müll und uninteressant. Du prüfst jedoch trotzdem alle 150 Zeichen des Arrays. Im ersten Durchlauf steht noch Speichermüll im Array, also wird die Anzahl der gefundenen Worte noch stimmen. Jetzt kommt der zweite Schleifendurchlauf. Du überschreibst den Anfang deines Arrays mit folgender Zeichenkette:
Platz 3: Federer passt auf.\0
Doch jetzt steht dahinter kein Speichermüll mehr, sondern der Rest der ersten Zeile, den du nicht überschrieben hast:
Platz 3: Federer passt auf.\0Garros verliert Melzer schließlich.\0
(Ich hab die Zeichen jetzt nicht gezählt, aber im Prinzip siehts so aus.)
Du müsstest jetzt wieder bis zum ersten \0 prüfen, aber du prüfst trotzdem alle 150 Zeichen im Array und findest das Wort im Rest der ersten Zeile. Da im dritten Durchlauf das selbe passiert wirst du in den 3 Zeilen das Wort 3 Mal finden, immer an der gleichen Stelle und eigentlich immer das selbe Wort der ersten Zeile.
Um das zu verhindern darfst du nicht den ganzen Array (alle 150 Zeichen) sondern nur bis zum ersten Vorkommen von \0 prüfen.
Verständlich? :)

tauberheli
Beiträge: 16
Registriert: Di Apr 27, 2010 3:47 pm

Re: Vorkommen von Wort in String zählen

Beitrag von tauberheli » Sa Sep 04, 2010 2:17 pm

Danke!

Ich hab mal den String character für character ausgegeben. (printf() hört ja bei '\0' auf.) Da ist wirklich viel Speichermüll drin!!!

AnGaiNoR
Beiträge: 212
Registriert: Sa Jul 19, 2008 7:07 pm
Wohnort: Dresden

Re: Vorkommen von Wort in String zählen

Beitrag von AnGaiNoR » Sa Sep 04, 2010 3:11 pm

Meine Lösung für das Problem wäre ein Endlicher Automat, der die Datei Zeichen für Zeichen mit fgetc ausliest. Jeder Zustand steht für einen "korrekt" ausgelesenen Buchstaben, dass heißt für einen Buchstaben des Wortes "verliert".
Am Anfang befindet sich der Automat im Startzustand ("nullter" Zustand) und hat noch keinen Buchstaben ausgelesen. Nach und nach werden alle Zeichen ausgelesen. Triffst du auf ein 'v', dann geht der Automat in den ersten Zustand über.
Im ersten Zustand muss als nächstes ein 'e' ausgelesen werden um in den zweiten Zustand zu kommen, ansonsten fällt der Automat in den Startzustand zurück. Dies wird solange fortgesetzt, bis sich der Automat im achten Zustand befindet ("verliert" hat acht Buchstaben). In diesem Fall wurde das Wort einmal ausgelesen und der Automat geht in den Startzustand über.

Quelltext:

Code: Alles auswählen

#include <stdio.h>

int main(void)
{
    FILE *file;     // Dateizeiger
    int count = 0;  // Anzahl der bereits gezählten Wörter
    int state;      // Zustand des Automaten
    int c;          // eingelesener Buchstabe

    // Datei öffnen und überprüfen
    file = fopen( "text.txt", "r" );
    if ( file == NULL )
    {
        printf( "Fehler beim Öffnen der Datei\n" );
        return -1;
    }

    // Datei auslesen (der Schleifenkopf ist nicht sehr anfängerfreundlich, sollte aber verständlich sein)
    while ( ( c = fgetc( file ) ) != EOF )
    {
        if ( state == 0 && c == 'v' )
            state = 1;
        else if ( state == 1 && c == 'e' )
            state = 2;
        else if ( state == 2 && c == 'r' )
            state = 3;
        else if ( state == 3 && c == 'l' )
            state = 4;
        else if ( state == 4 && c == 'i' )
            state = 5;
        else if ( state == 5 && c == 'e' )
            state = 6;
        else if ( state == 6 && c == 'r' )
            state = 7;
        else if ( state == 7 && c == 't' )
        {
            state = 0;
            ++count;
        }
        else
            state = 0;
    }

    // Datei schließen
    fclose( file );

    // Ausgabe
    printf( "%d\n", count );

    // Programm beenden
    return 0;
}
Natürlich könnte man das Programm auch dynamisieren, so dass man das Suchwort ändern kann, ohne viel ändern zu müssen, aber das war ja nicht die Frage.
Physics is like sex: sure, it may give some practical result, but that's not why we do it.
(Richard P. Feynman)

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Vorkommen von Wort in String zählen

Beitrag von nufan » Sa Sep 04, 2010 6:26 pm

Das mit den ganzen if's kann man doch deutlich schöner lösen...

Code: Alles auswählen

const char *const word = "verliert";    // gesuchtes Wort
int state = 0;                         // aktueller Status, Index von "word"

while ( ( c = fgetc( file ) ) != EOF )
{
  if(c == word[state])           // passender Buchstabe
  {
    state++;                   // nach nächstem Buchstaben suchen
    if(word[state] == '\0')    // Wort wurde komplett gefunden
    {
      count++;                 // Anzahl der Vorkommnisse erhöhen
      state = 0;               // wieder den Anfang des Wortes suchen
    }
  }
  else                           // falscher Buchstabe
    state = 0;                   // wieder den Anfang des Wortes suchen
}
Hier ist die Variable "state" der Index des als nächstes benötigten Buchstaben im Hilfs-String "word". Wird dieser Buchstabe aus der Datei gelesen wird der Index erhöht und es wird nach dem nächsten Buchstaben gesucht. Ist dieser Buchstabe '\0' (also das Ende des Strings "word" erreicht) wurde das Wort komplett gefunden und die Anzahl wird erhöht und wieder der erste Buchstabe gesucht. Passt der Buchstabe aus der Datei nicht, wird natürlich auch wieder nach dem ersten Buchstaben gesucht.

AnGaiNoR
Beiträge: 212
Registriert: Sa Jul 19, 2008 7:07 pm
Wohnort: Dresden

Re: Vorkommen von Wort in String zählen

Beitrag von AnGaiNoR » Sa Sep 04, 2010 10:07 pm

dani93 hat geschrieben:Das mit den ganzen if's kann man doch deutlich schöner lösen...
Das habe ich ja in meinem letzten Satz auch gesagt, aber man muss ja nicht gleich alles vorsagen. ;)
Physics is like sex: sure, it may give some practical result, but that's not why we do it.
(Richard P. Feynman)

Antworten