Info2P5/28.6.3_wortstat.c
2025-05-29 09:38:08 +02:00

107 lines
3.7 KiB
C

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