halo
This commit is contained in:
parent
c0160343e0
commit
1d16bb3625
@ -3,105 +3,105 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#define MAXWORT 100 // Maximale Wortlänge
|
#define MAXWORD 100 // Maximale Wortlänge
|
||||||
|
|
||||||
// Definition eines Baumknotens für ein Wort
|
// Definition eines Baumknotens für ein Wort
|
||||||
typedef struct BaumKnoten {
|
typedef struct TreeNode {
|
||||||
char *wort; // Das gespeicherte Wort
|
char *word; // Das gespeicherte Wort
|
||||||
int anzahl; // Wie oft das Wort vorkam
|
int count; // Wie oft das Wort vorkam
|
||||||
struct BaumKnoten *links; // Linker Teilbaum (Wörter, die alphabetisch davor kommen)
|
struct TreeNode *left; // Linker Teilbaum (Wörter, die alphabetisch davor kommen)
|
||||||
struct BaumKnoten *rechts; // Rechter Teilbaum (Wörter, die alphabetisch danach kommen)
|
struct TreeNode *right; // Rechter Teilbaum (Wörter, die alphabetisch danach kommen)
|
||||||
} BaumKnoten_t;
|
} TreeNode_t;
|
||||||
|
|
||||||
// Funktion zum Einfügen eines Wortes in den Baum
|
// Funktion zum Einfügen eines Wortes in den Baum
|
||||||
// Falls das Wort schon existiert, wird der Zähler erhöht
|
// Falls das Wort schon existiert, wird der Zähler erhöht
|
||||||
BaumKnoten_t* einfuegen(BaumKnoten_t *wurzel, const char *wort) {
|
TreeNode_t* insert(TreeNode_t *root, const char *word) {
|
||||||
if (wurzel == NULL) {
|
if (root == NULL) {
|
||||||
// Neuer Knoten, falls das Wort noch nicht im Baum ist
|
// Neuer Knoten, falls das Wort noch nicht im Baum ist
|
||||||
BaumKnoten_t *neu = malloc(sizeof(BaumKnoten_t));
|
TreeNode_t *newNode = malloc(sizeof(TreeNode_t));
|
||||||
if (!neu) {
|
if (!newNode) {
|
||||||
perror("Speicherfehler");
|
perror("Speicherfehler");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
neu->wort = strdup(wort); // Wort kopieren und speichern
|
newNode->word = strdup(word); // Wort kopieren und speichern
|
||||||
neu->anzahl = 1; // Erstes Vorkommen
|
newNode->count = 1; // Erstes Vorkommen
|
||||||
neu->links = neu->rechts = NULL; // Noch keine Kinder
|
newNode->left = newNode->right = NULL; // Noch keine Kinder
|
||||||
return neu;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmp = strcmp(wort, wurzel->wort); // Alphabetischer Vergleich
|
int cmp = strcmp(word, root->word); // Alphabetischer Vergleich
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
// Wort schon vorhanden: Zähler erhöhen
|
// Wort schon vorhanden: Zähler erhöhen
|
||||||
wurzel->anzahl++;
|
root->count++;
|
||||||
} else if (cmp < 0) {
|
} else if (cmp < 0) {
|
||||||
// Wort ist alphabetisch VOR dem aktuellen Knoten: links einfügen
|
// Wort ist alphabetisch VOR dem aktuellen Knoten: links einfügen
|
||||||
wurzel->links = einfuegen(wurzel->links, wort);
|
root->left = insert(root->left, word);
|
||||||
} else {
|
} else {
|
||||||
// Wort ist alphabetisch NACH dem aktuellen Knoten: rechts einfügen
|
// Wort ist alphabetisch NACH dem aktuellen Knoten: rechts einfügen
|
||||||
wurzel->rechts = einfuegen(wurzel->rechts, wort);
|
root->right = insert(root->right, word);
|
||||||
}
|
}
|
||||||
return wurzel;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inorder-Ausgabe: Gibt die Wörter alphabetisch sortiert mit Häufigkeit aus
|
// Inorder-Ausgabe: Gibt die Wörter alphabetisch sortiert mit Häufigkeit aus
|
||||||
void ausgabe(BaumKnoten_t *wurzel) {
|
void printTree(TreeNode_t *root) {
|
||||||
if (wurzel == NULL)
|
if (root == NULL)
|
||||||
return;
|
return;
|
||||||
ausgabe(wurzel->links); // Erst linker Teilbaum
|
printTree(root->left); // Erst linker Teilbaum
|
||||||
printf("%-12s : %d\n", wurzel->wort, wurzel->anzahl); // Dann aktueller Knoten
|
printf("%-12s : %d\n", root->word, root->count); // Dann aktueller Knoten
|
||||||
ausgabe(wurzel->rechts); // Dann rechter Teilbaum
|
printTree(root->right); // Dann rechter Teilbaum
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gibt den belegten Speicher des Baumes wieder frei
|
// Gibt den belegten Speicher des Baumes wieder frei
|
||||||
void freigeben(BaumKnoten_t *wurzel) {
|
void freeTree(TreeNode_t *root) {
|
||||||
if (wurzel == NULL)
|
if (root == NULL)
|
||||||
return;
|
return;
|
||||||
freigeben(wurzel->links); // Erst linker Teilbaum
|
freeTree(root->left); // Erst linker Teilbaum
|
||||||
freigeben(wurzel->rechts); // Dann rechter Teilbaum
|
freeTree(root->right); // Dann rechter Teilbaum
|
||||||
free(wurzel->wort); // Erst das Wort freigeben
|
free(root->word); // Erst das Wort freigeben
|
||||||
free(wurzel); // Dann den Knoten selbst
|
free(root); // Dann den Knoten selbst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüft, ob ein Zeichen ein Buchstabe ist (a-z, A-Z)
|
// Prüft, ob ein Zeichen ein Buchstabe ist (a-z, A-Z)
|
||||||
int istBuchstabe(char c) {
|
int isLetter(char c) {
|
||||||
return isalpha((unsigned char)c);
|
return isalpha((unsigned char)c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Liest Wörter aus stdin, zählt sie und gibt die Statistik aus
|
// Liest Wörter aus stdin, zählt sie und gibt die Statistik aus
|
||||||
void liesTextUndErzeugeStatistik() {
|
void readTextAndPrintStats() {
|
||||||
char wort[MAXWORT]; // Zwischenspeicher für das aktuelle Wort
|
char word[MAXWORD]; // Zwischenspeicher für das aktuelle Wort
|
||||||
int index = 0; // Position im Wort
|
int index = 0; // Position im Wort
|
||||||
int c; // Aktuelles Zeichen
|
int c; // Aktuelles Zeichen
|
||||||
BaumKnoten_t *baum = NULL; // Wurzel des Baumes
|
TreeNode_t *tree = NULL; // Wurzel des Baumes
|
||||||
|
|
||||||
// Zeichenweise Einlesen bis Dateiende (EOF)
|
// Zeichenweise Einlesen bis Dateiende (EOF)
|
||||||
while ((c = getchar()) != EOF) {
|
while ((c = getchar()) != EOF) {
|
||||||
if (istBuchstabe(c)) {
|
if (isLetter(c)) {
|
||||||
// Nur Buchstaben werden akzeptiert, alles in Kleinbuchstaben
|
// Nur Buchstaben werden akzeptiert, alles in Kleinbuchstaben
|
||||||
if (index < MAXWORT - 1)
|
if (index < MAXWORD - 1)
|
||||||
wort[index++] = tolower(c);
|
word[index++] = tolower(c);
|
||||||
} else if (index > 0) {
|
} else if (index > 0) {
|
||||||
// Wortende erreicht (kein Buchstabe mehr)
|
// Wortende erreicht (kein Buchstabe mehr)
|
||||||
wort[index] = '\0'; // String abschließen
|
word[index] = '\0'; // String abschließen
|
||||||
baum = einfuegen(baum, wort); // Wort in Baum einfügen
|
tree = insert(tree, word); // Wort in Baum einfügen
|
||||||
index = 0; // Für das nächste Wort zurücksetzen
|
index = 0; // Für das nächste Wort zurücksetzen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Falls am Ende noch ein Wort übrig ist (z.B. Datei endet ohne Leerzeichen)
|
// Falls am Ende noch ein Wort übrig ist (z.B. Datei endet ohne Leerzeichen)
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
wort[index] = '\0';
|
word[index] = '\0';
|
||||||
baum = einfuegen(baum, wort);
|
tree = insert(tree, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
ausgabe(baum); // Statistik ausgeben (alphabetisch sortiert)
|
printTree(tree); // Statistik ausgeben (alphabetisch sortiert)
|
||||||
freigeben(baum); // Speicher aufräumen
|
freeTree(tree); // Speicher aufräumen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hauptfunktion: Startet das Programm
|
// Hauptfunktion: Startet das Programm
|
||||||
int main() {
|
int main() {
|
||||||
liesTextUndErzeugeStatistik();
|
readTextAndPrintStats();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kompilieren: gcc -o wortstat wortstat.c
|
// Kompilieren: gcc -o wordstat wordstat.c
|
||||||
// Ausführen: ./wortstat < schwafel.txt
|
// Ausführen: ./wordstat < somefile.txt
|
Loading…
x
Reference in New Issue
Block a user