diff --git a/28.4.3_romzahl.c b/28.4.3_romzahl.c index 972ff3f..dde097c 100644 --- a/28.4.3_romzahl.c +++ b/28.4.3_romzahl.c @@ -1,81 +1,60 @@ #include // Struktur zur Abbildung von arabisch → römisch - -typedef struct { - - int wert; - - const char *zeichen; - -} Roemisch; +typedef struct Roemisch { + int wert; // Der arabische Zahlenwert (z.B. 1000) + const char *zeichen; // Das zugehörige römische Zeichen (z.B. "M") +} Roemisch_t; // Tabelle in absteigender Reihenfolge - -Roemisch roemischTabelle[] = { - +// Jede Zeile enthält einen Wert und das zugehörige römische Zeichen +Roemisch_t roemischTabelle[] = { {1000, "M"}, - {900, "CM"}, - {500, "D"}, - {400, "CD"}, - {100, "C"}, - {90, "XC"}, - {50, "L"}, - {40, "XL"}, - {10, "X"}, - {9, "IX"}, - {5, "V"}, - {4, "IV"}, - {1, "I"} - }; // Hauptfunktion - int main() { - int zahl; + // Benutzer nach einer Zahl fragen printf("Zu wandelnde Zahl: "); - scanf("%d", &zahl); + // Überprüfen, ob die Zahl im erlaubten Bereich liegt (1 bis 3999) if (zahl <= 0 || zahl > 3999) { - printf("Nur Zahlen zwischen 1 und 3999 erlaubt!\n"); - - return 1; - + return 1; // Programm mit Fehlercode beenden } + // Die eingegebene Zahl ausgeben printf("... %d = ", zahl); - for (int i = 0; i < sizeof(roemischTabelle) / sizeof(Roemisch); i++) { - + // Über die Tabelle iterieren, um die römische Zahl zu erzeugen + // sizeof(roemischTabelle) / sizeof(Roemisch) berechnet die Anzahl der Einträge in der Tabelle + for (int i = 0; i < sizeof(roemischTabelle) / sizeof(Roemisch_t); i++) { + // Solange der aktuelle Wert in die Zahl "passt" while (zahl >= roemischTabelle[i].wert) { - + // Das zugehörige römische Zeichen ausgeben printf("%s", roemischTabelle[i].zeichen); - + // Den Wert von der Zahl abziehen zahl -= roemischTabelle[i].wert; - } - } + // Zeilenumbruch am Ende printf("\n"); - return 0; - -} + return 0; // Erfolgreiches Programmende +} \ No newline at end of file diff --git a/28.6.3_wortstat.c b/28.6.3_wortstat.c index 1743292..c1abf4b 100644 --- a/28.6.3_wortstat.c +++ b/28.6.3_wortstat.c @@ -1,172 +1,107 @@ #include - #include - #include - #include -#define MAXWORT 100 - -// Baumstruktur für ein Wort +#define MAXWORT 100 // Maximale Wortlänge +// Definition eines Baumknotens für ein Wort typedef struct BaumKnoten { + char *wort; // Das gespeicherte Wort + int anzahl; // Wie oft das Wort vorkam + struct BaumKnoten *links; // Linker Teilbaum (Wörter, die alphabetisch davor kommen) + struct BaumKnoten *rechts; // Rechter Teilbaum (Wörter, die alphabetisch danach kommen) +} BaumKnoten_t; - char *wort; - - int anzahl; - - struct BaumKnoten *links; - - struct BaumKnoten *rechts; - -} BaumKnoten; - -// Neues Wort in den Baum einfügen oder Zähler erhöhen - -BaumKnoten* einfuegen(BaumKnoten *wurzel, const char *wort) { - +// Funktion zum Einfügen eines Wortes in den Baum +// Falls das Wort schon existiert, wird der Zähler erhöht +BaumKnoten_t* einfuegen(BaumKnoten_t *wurzel, const char *wort) { if (wurzel == NULL) { - - BaumKnoten *neu = malloc(sizeof(BaumKnoten)); - + // Neuer Knoten, falls das Wort noch nicht im Baum ist + BaumKnoten_t *neu = malloc(sizeof(BaumKnoten_t)); if (!neu) { - perror("Speicherfehler"); - exit(EXIT_FAILURE); - } - - neu->wort = strdup(wort); - - neu->anzahl = 1; - - neu->links = neu->rechts = NULL; - + neu->wort = strdup(wort); // Wort kopieren und speichern + neu->anzahl = 1; // Erstes Vorkommen + neu->links = neu->rechts = NULL; // Noch keine Kinder return neu; - } - int cmp = strcmp(wort, wurzel->wort); - + int cmp = strcmp(wort, wurzel->wort); // Alphabetischer Vergleich if (cmp == 0) { - + // Wort schon vorhanden: Zähler erhöhen wurzel->anzahl++; - } else if (cmp < 0) { - + // Wort ist alphabetisch VOR dem aktuellen Knoten: links einfügen wurzel->links = einfuegen(wurzel->links, wort); - } else { - + // Wort ist alphabetisch NACH dem aktuellen Knoten: rechts einfügen wurzel->rechts = einfuegen(wurzel->rechts, wort); - } - return wurzel; - } -// Inorder-Ausgabe des Baumes - -void ausgabe(BaumKnoten *wurzel) { - +// Inorder-Ausgabe: Gibt die Wörter alphabetisch sortiert mit Häufigkeit aus +void ausgabe(BaumKnoten_t *wurzel) { if (wurzel == NULL) - return; - - ausgabe(wurzel->links); - - printf("%-12s : %d\n", wurzel->wort, wurzel->anzahl); - - ausgabe(wurzel->rechts); - + ausgabe(wurzel->links); // Erst linker Teilbaum + printf("%-12s : %d\n", wurzel->wort, wurzel->anzahl); // Dann aktueller Knoten + ausgabe(wurzel->rechts); // Dann rechter Teilbaum } -// Speicher freigeben - -void freigeben(BaumKnoten *wurzel) { - +// Gibt den belegten Speicher des Baumes wieder frei +void freigeben(BaumKnoten_t *wurzel) { if (wurzel == NULL) - return; - - freigeben(wurzel->links); - - freigeben(wurzel->rechts); - - free(wurzel->wort); - - free(wurzel); - + freigeben(wurzel->links); // Erst linker Teilbaum + freigeben(wurzel->rechts); // Dann rechter Teilbaum + free(wurzel->wort); // Erst das Wort freigeben + free(wurzel); // Dann den Knoten selbst } -// Nur Buchstaben akzeptieren - +// Prüft, ob ein Zeichen ein Buchstabe ist (a-z, A-Z) int istBuchstabe(char c) { - return isalpha((unsigned char)c); - } -// Einlesen der Wörter aus stdin - +// Liest Wörter aus stdin, zählt sie und gibt die Statistik aus void liesTextUndErzeugeStatistik() { + char wort[MAXWORT]; // Zwischenspeicher für das aktuelle Wort + int index = 0; // Position im Wort + int c; // Aktuelles Zeichen + BaumKnoten_t *baum = NULL; // Wurzel des Baumes - char wort[MAXWORT]; - - int index = 0; - - int c; - - BaumKnoten *baum = NULL; - + // Zeichenweise Einlesen bis Dateiende (EOF) while ((c = getchar()) != EOF) { - if (istBuchstabe(c)) { - + // Nur Buchstaben werden akzeptiert, alles in Kleinbuchstaben if (index < MAXWORT - 1) - wort[index++] = tolower(c); - } else if (index > 0) { - - wort[index] = '\0'; - - baum = einfuegen(baum, wort); - - index = 0; - + // Wortende erreicht (kein Buchstabe mehr) + wort[index] = '\0'; // String abschließen + baum = einfuegen(baum, wort); // Wort in Baum einfügen + index = 0; // Für das nächste Wort zurücksetzen } - } - - // letztes Wort, falls am Ende kein Trennzeichen - + // Falls am Ende noch ein Wort übrig ist (z.B. Datei endet ohne Leerzeichen) if (index > 0) { - wort[index] = '\0'; - baum = einfuegen(baum, wort); - } - ausgabe(baum); - - freigeben(baum); - + ausgabe(baum); // Statistik ausgeben (alphabetisch sortiert) + freigeben(baum); // Speicher aufräumen } -// Hauptfunktion - +// Hauptfunktion: Startet das Programm int main() { - liesTextUndErzeugeStatistik(); - return 0; - } -//gcc -o wortstat wortstat.c -//./wortstat < schwafel.txt \ No newline at end of file +// Kompilieren: gcc -o wortstat wortstat.c +// Ausführen: ./wortstat < schwafel.txt \ No newline at end of file diff --git a/TestMatricOp.c b/TestMatricOp.c index f839f5f..cd78207 100644 --- a/TestMatricOp.c +++ b/TestMatricOp.c @@ -1,62 +1,49 @@ #include - #include "matrixOp.h" int main() { - - Matrix *a = CreateMatrix(2, 3, 1.0); - - Matrix *b = CreateMatrix(2, 3, 7.0); + // Erstellt zwei 2x3-Matrizen mit aufsteigenden Werten + Matrix *a = CreateMatrix(2, 3, 1.0); // 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 + Matrix *b = CreateMatrix(2, 3, 7.0); // 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 Matrix *c, *d, *e, *f; printf("Matrix a:\n"); - PrintMatrix(a); printf("Matrix b:\n"); - PrintMatrix(b); + // Addition: a + b c = AddMatrix(a, b); - printf("a + b:\n"); - PrintMatrix(c); + // Subtraktion: a - b d = SubMatrix(a, b); - printf("a - b:\n"); - PrintMatrix(d); + // Transponieren von a e = TransposeMatrix(a); - printf("Transpose of a:\n"); - PrintMatrix(e); + // Matrixmultiplikation: a * a^T f = MulMatrix(a, e); - printf("a * a^T:\n"); - PrintMatrix(f); + // Determinante der Ergebnismatrix (nur für 2x2 möglich) printf("det(a * a^T): %.2f\n", DetMatrix(f)); + // Speicher wieder freigeben FreeMatrix(a); - FreeMatrix(b); - FreeMatrix(c); - FreeMatrix(d); - FreeMatrix(e); - FreeMatrix(f); return 0; - -} - \ No newline at end of file +} \ No newline at end of file diff --git a/matrixOp.c b/matrixOp.c index ee50687..4861a18 100644 --- a/matrixOp.c +++ b/matrixOp.c @@ -2,26 +2,32 @@ #include #include #include "matrixOp.h" + +// Erstellt eine Matrix mit allen Einträgen 0 Matrix* CreateMatrixZero(int rows, int cols) { - Matrix *m = malloc(sizeof(Matrix)); + Matrix *m = malloc(sizeof(Matrix)); // Speicher für Matrix-Struktur m->rows = rows; m->cols = cols; - m->data = malloc(rows * sizeof(double*)); + m->data = malloc(rows * sizeof(double*)); // Speicher für Zeilenzeiger for (int i = 0; i < rows; i++) { - m->data[i] = calloc(cols, sizeof(double)); + m->data[i] = calloc(cols, sizeof(double)); // Speicher für jede Zeile, initialisiert mit 0 } return m; } + +// Erstellt eine Matrix mit Zufallswerten zwischen -100 und 99 Matrix* CreateMatrixRand(int rows, int cols) { - srand(time(NULL)); + srand(time(NULL)); // Initialisiert Zufallszahlengenerator (Achtung: bei jedem Aufruf neu!) Matrix *m = CreateMatrixZero(rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { - m->data[i][j] = (rand() % 200 - 100) / 1.0; // -100 bis 99 + m->data[i][j] = (rand() % 200 - 100) / 1.0; // Werte von -100 bis 99 } } return m; } + +// Erstellt eine Matrix, deren Einträge mit startValue beginnen und dann hochzählen Matrix* CreateMatrix(int rows, int cols, double startValue) { Matrix *m = CreateMatrixZero(rows, cols); double val = startValue; @@ -32,13 +38,17 @@ Matrix* CreateMatrix(int rows, int cols, double startValue) { } return m; } + +// Gibt den Speicher einer Matrix wieder frei void FreeMatrix(Matrix *m) { for (int i = 0; i < m->rows; i++) { - free(m->data[i]); + free(m->data[i]); // Jede Zeile freigeben } - free(m->data); - free(m); + free(m->data); // Zeilenzeiger-Array freigeben + free(m); // Matrix-Struktur freigeben } + +// Gibt die Matrix schön formatiert auf der Konsole aus void PrintMatrix(Matrix *m) { for (int i = 0; i < m->rows; i++) { for (int j = 0; j < m->cols; j++) { @@ -47,8 +57,10 @@ void PrintMatrix(Matrix *m) { printf("\n"); } } + +// Addiert zwei Matrizen gleicher Größe Matrix* AddMatrix(Matrix *a, Matrix *b) { - if (a->rows != b->rows || a->cols != b->cols) return NULL; + if (a->rows != b->rows || a->cols != b->cols) return NULL; // Nur gleiche Größe erlaubt Matrix *m = CreateMatrixZero(a->rows, a->cols); for (int i = 0; i < m->rows; i++) { for (int j = 0; j < m->cols; j++) { @@ -57,6 +69,8 @@ Matrix* AddMatrix(Matrix *a, Matrix *b) { } return m; } + +// Subtrahiert zwei Matrizen gleicher Größe Matrix* SubMatrix(Matrix *a, Matrix *b) { if (a->rows != b->rows || a->cols != b->cols) return NULL; Matrix *m = CreateMatrixZero(a->rows, a->cols); @@ -67,8 +81,10 @@ Matrix* SubMatrix(Matrix *a, Matrix *b) { } return m; } + +// Transponiert eine Matrix (Zeilen und Spalten vertauschen) Matrix* TransposeMatrix(Matrix *a) { - Matrix *m = CreateMatrixZero(a->cols, a->rows); + Matrix *m = CreateMatrixZero(a->cols, a->rows); // Zeilen und Spalten vertauscht for (int i = 0; i < a->rows; i++) { for (int j = 0; j < a->cols; j++) { m->data[j][i] = a->data[i][j]; @@ -76,8 +92,10 @@ Matrix* TransposeMatrix(Matrix *a) { } return m; } + +// Multipliziert zwei Matrizen (a: m x n, b: n x p) Matrix* MulMatrix(Matrix *a, Matrix *b) { - if (a->cols != b->rows) return NULL; + if (a->cols != b->rows) return NULL; // Nur möglich, wenn Spalten von a == Zeilen von b Matrix *m = CreateMatrixZero(a->rows, b->cols); for (int i = 0; i < a->rows; i++) { for (int j = 0; j < b->cols; j++) { @@ -88,11 +106,14 @@ Matrix* MulMatrix(Matrix *a, Matrix *b) { } return m; } + +// Berechnet die Determinante einer 2x2-Matrix double DetMatrix(Matrix *m) { - if (m->rows != m->cols) return 0; + if (m->rows != m->cols) return 0; // Nur quadratische Matrizen if (m->rows == 2) { + // Formel: ad - bc return m->data[0][0] * m->data[1][1] - m->data[0][1] * m->data[1][0]; } - // Optional: Erweiterung für n > 2 + // Für größere Matrizen nicht implementiert return 0; } \ No newline at end of file