This commit is contained in:
Bora Zuenbuelkoek 2025-05-29 09:38:08 +02:00
parent c0160343e0
commit 1d16bb3625

View File

@ -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