Ah - danke für die Hinweise.
Würde mich gern mal mit C befassen
-
Ingo -
16. Februar 2023 um 09:08 -
Erledigt
Es gibt 196 Antworten in diesem Thema, welches 20.613 mal aufgerufen wurde. Der letzte Beitrag (
-
-
Wie ergibt sich aus den CSV-Daten, daß Hugo Huber der Vater von Albert Huber ist?
-
Wie ergibt sich aus den CSV-Daten, daß Hugo Huber der Vater von Albert Huber ist?
Das ergibt sich aus dem Dateiformat. 1. Person, 2. Vater, 3. Mutter. Aber, ja, das würde problematisch werden wenn die Eltern mehr als ein Kind hätten. Man kann natürlich einen Verweis einbauen, wer die Eltern von welcher Person sind, aber das wird dann schon komplizierter. Der Verweis auf den Namen reicht nicht, weil der nicht eindeutig sein muss. Man könnte natürlich auch einen Indexverweis verwenden oder eine PersonenId vergeben, was auf jeden Fall die beste Variante wäre, weil dann die Reihenfolge egal wäre und es auch keine Rolle spielt ob für jemanden nur der Vater oder nur die Mutter vorhanden ist.
-
Wie ergibt sich aus den CSV-Daten, daß Hugo Huber der Vater von Albert Huber ist?
Das ergibt sich aus dem Dateiformat. 1. Person, 2. Vater, 3. Mutter.
Leider nein:
Hugo Huber ist 5., nicht 2. Da bestehen noch mehr Beziehungen zwischen den einzelnen Zeilen (Stammbaum), die aber nicht so offensichtlich sind.
Woher weiß ich das? Ich hab' das "1 - 2 - 3" in Python gemacht, und festgestellt, daß das nicht ausreicht, um denselben Output zu bekommen.
Python
Alles anzeigen#!/usr/bin/python # coding: utf-8 class Person: def __init__(self, name, gebdat): self.name = name self.gebdat = gebdat self.vater = None self.mutter = None kinder = [] vaeter = [] muetter = [] fh = open("Daten.txt", "r") l = "k" kcount = -1 while True: line = fh.readline() if not line: break line = line.rstrip() a = line.split(",") if l == "k": kind = Person(a[0], int(a[1])) kinder.append(kind) l = "v" kcount += 1 continue if l == "v": vater = Person(a[0], int(a[1])) vaeter.append(vater) kinder[kcount].vater = vater l = "m" continue if l == "m": mutter = Person(a[0], int(a[1])) muetter.append(mutter) kinder[kcount].mutter = mutter l = "k" continue fh.close() for k in kinder: print k.name print k.vater.name print k.mutter.name print -
Wie ergibt sich aus den CSV-Daten, daß Hugo Huber der Vater von Albert Huber ist?
Das ergibt sich aus dem Dateiformat. 1. Person, 2. Vater, 3. Mutter.
Leider nein:
Hugo Huber ist 5., nicht 2. Da bestehen noch mehr Beziehungen zwischen den einzelnen Zeilen (Stammbaum), die aber nicht so offensichtlich sind.
Woher weiß ich das? Ich hab' das "1 - 2 - 3" in Python gemacht, und festgestellt, daß das nicht ausreicht, um denselben Output zu bekommen.
Python
Alles anzeigen#!/usr/bin/python # coding: utf-8 class Person: def __init__(self, name, gebdat): self.name = name self.gebdat = gebdat self.vater = None self.mutter = None kinder = [] vaeter = [] muetter = [] fh = open("Daten.txt", "r") l = "k" kcount = -1 while True: line = fh.readline() if not line: break line = line.rstrip() a = line.split(",") if l == "k": kind = Person(a[0], int(a[1])) kinder.append(kind) l = "v" kcount += 1 continue if l == "v": vater = Person(a[0], int(a[1])) vaeter.append(vater) kinder[kcount].vater = vater l = "m" continue if l == "m": mutter = Person(a[0], int(a[1])) muetter.append(mutter) kinder[kcount].mutter = mutter l = "k" continue fh.close() for k in kinder: print k.name print k.vater.name print k.mutter.name printEben mußte ich mir die Datei nochmal anschauen. Also die stimmt:
Erst kommt der Sohn, Hansi Huber, dann die Eltern: Robert Huber und Ute Schmitt, dann die Großeltern: Albert Huber, Charlotte Klein, Utz Lang und Berta Waldhorst. Dann die Urgroßeltern: Hugo Huber, usw.
Klar kann man noch die Geschwister, 1. und weitere Ehefrauen berücksichtigen etc.
Aber mir ging es hier nur um 1.: Die Pointertechnik in einer Struktur. 2.: Daten aus einer Datei auslesen und 3.: Rekursives Durchsuchen einer Baumstruktur.
Zum Thema Baumstruktur:
So wie es in dem Bsp. mit einem Array pf mit fester Anzahl Elementen ist, ist ja eigentlich auch nicht so toll.
Normalerweise würde man das doch folgendermaßen machen oder?:
Datensatz einlesen, Speicher für das Strukt "Person" allozieren und in den Baum hängen.
Mit den Zeigern auf die Baumelement ist ja dann auch das Einfügen, Löschen und Verschieben ganz einfach. Einfach nur die Zeiger umbiegen.
(Hatte ich letztens mal in dem Buch "C von A bis Z" von Jürgen Wolf entdeckt und direkt bestellt. Das gibt's auch online.)
-
Eben mußte ich mir die Datei nochmal anschauen. Also die stimmt:Erst kommt der Sohn, ... dann die Eltern ... dann die Großeltern ... dann die Urgroßeltern
Ah, danke! Dann also so (ist ja nicht so ganz einfach, das muß man erstmal aufdröseln) (Sowas braucht man normalerweise, um die gesetzliche Erbfolge zu bestimmen.
)Code
Alles anzeigen1 Hansi Huber,1970 ------------------------------ A. Eltern von Hansi Huber: 1.1 Robert Huber,1950 1.2 Ute Schmitt,1951 ------------------------------ B. Großeltern von Hansi Huber: - Eltern von Robert Huber: 1.1.1 Albert Huber,1910 1.1.2 Charlotte Klein,1912 - Eltern von Ute Schmitt: 1.2.1 Utz Lang,1917 1.2.2 Berta Waldhorst,1920 ------------------------------ C. Urgroßeltern von Hansi Huber: Großeltern von Robert Huber: - Eltern von Albert Huber: 1.1.1.1 Hugo Huber,1889 1.1.1.2 Ottonia Ackermann,1890 - Eltern von Charlotte Klein: 1.1.2.1 Berthold Groß,1885 1.1.2.2 Luise Barwig,1887 Großeltern von Ute Schmitt: - Eltern von Utz Lang: 1.2.1.1 Jakob Heuss,1878 1.2.1.2 Henriette Schwarz,1879 - Eltern von Berta Waldhorst: 1.2.2.1 Wilhelm Krause,1876 1.2.2.2 Josefine Weber,1875Bzgl. der Umsetzung würde man wohl einen "binären Baum" verwenden. Ich finde hier ein C-Tutorial dazu:
Bitte melde dich an, um dieses Medienelement zu sehen.
Und Bitte melde dich an, um diesen Link zu sehen. den zugehörigen Beispielcode.
Ja gut, im Lehrbuch des (ersten Semesters des) Fernstudiums zur strukturierten Programmierung (in dem Fall in Pascal) waren "binäre Bäume" aber auch eines der letzten, also fortgeschrittensten Kapitel.
-
Ja gut, im Lehrbuch des (ersten Semesters des) Fernstudiums zur strukturierten Programmierung (in dem Fall in Pascal) waren "binäre Bäume" aber auch eines der letzten, also fortgeschrittensten Kapitel.
Wir hatten das schon in der Schule im Informatik-Grundkurs, bevor es mit Assembler weiterging und wir Einplatinencomputer gebaut haben.
-
Wir hatten das schon in der Schule im Informatik-Grundkurs, bevor es mit Assembler weiterging und wir Einplatinencomputer gebaut haben.
Pics, or it didn't happen.

@all: Ich knabber gerade immer noch daran, wie man einen binären Baum am besten in einer Textdatei speichert, bzw. wie man zwischen einem binärem Baum und einem Array hin- und herkonvertiert. Dazu finde ich schon was, da ist die Rede von "Preorder" und "Inorder" bei dem Baum. Ach, es wird schon wieder so kompliziert, vor allem in C.
Bitte melde dich an, um diesen Link zu sehen.
Bitte melde dich an, um diesen Link zu sehen.
Wie man es dreht und wendet, die Dinge sind in Python einfach einfacher, und dadurch schneller getan ...
-
Ich würd das so als CSV Datei speichern.
# ID; Daten; Söhne
0; "Paps"; 2,3
Das 3. Element zerlegst Du dann mit split und bekommst die IDs aller Söhne. So irgendwie halt
-
Das 3. Element zerlegst Du dann mit split und bekommst die IDs aller Söhne. So irgendwie halt
Das hätte ich auch so gedacht, mit 'ner ID. In dem ersten verlinkten Artikel in meinem Posting vorher steht aber, es genüge schon, die Stellen des Arrays dafür zu nutzen.
Dafür müsse der Baum aber in einem bestimmten Format sein.
So daß dann also eindeutig ist, "Stelle 0" im Array bedeutet "Position sowieso" im Baum.
Fehlen gewisse Äste im Baum (in Ingos Beispiel bisher nicht der Fall), müsse man an den entsprechenden Stellen im Array eben "-1" oder sowas schreiben.
Insgesamt so ein typisches abstraktes Informatikproblem.

Edit: Ich dachte gerade, sowas kapseln Informatiker doch gern in Modulen, so daß jemand wie ich sich nicht im Detail damit zu beschäftigen braucht. Und Bitte melde dich an, um diesen Link zu sehen. ...
-
Alles anzeigen
Das 3. Element zerlegst Du dann mit split und bekommst die IDs aller Söhne. So irgendwie halt
Das hätte ich auch so gedacht, mit 'ner ID. In dem ersten verlinkten Artikel in meinem Posting vorher steht aber, es genüge schon, die Stellen des Arrays dafür zu nutzen.
Dafür müsse der Baum aber in einem bestimmten Format sein.
So daß dann also eindeutig ist, "Stelle 0" im Array bedeutet "Position sowieso" im Baum.
Fehlen gewisse Äste im Baum (in Ingos Beispiel bisher nicht der Fall), müsse man an den entsprechenden Stellen im Array eben "-1" oder sowas schreiben.
Insgesamt so ein typisches abstraktes Informatikproblem.

Die IDs ersetzen funktional die Pointer des Baums im Speicher.
Insofern sollte es reichen, als ID dann die Position des bezeigten Elements relativ zum Dateianfang anzugeben, z.B. gezählt in Bytes.
-
Insofern sollte es reichen, als ID dann die Position des bezeigten Elements relativ zum Dateianfang anzugeben, z.B. gezählt in Bytes.
Den Index des Elements, aber nicht den Offset in Bytes. Der Offset wäre etwas problematisch (z.B. bei Erweiterungen) und wäre auch nicht unbedingt portierbar.
-
Insofern sollte es reichen, als ID dann die Position des bezeigten Elements relativ zum Dateianfang anzugeben, z.B. gezählt in Bytes.
Den Index des Elements, aber nicht den Offset in Bytes. Der Offset wäre etwas problematisch (z.B. bei Erweiterungen) und wäre auch nicht unbedingt portierbar.
Ich hatte das als Übungsaufgabe fürs Serialisieren und Deserialisieren verstanden, bei der nicht erwartet wird, dass in den Dump-Dateien rumeditiert wird.
Aber Zeilennummer als ID ist sinnvoller für ein CSV-Textformat, ja.
-
Ich hatte das als Übungsaufgabe fürs Serialisieren und Deserialisieren verstanden, bei der nicht erwartet wird, dass in den Dump-Dateien rumeditiert wird.
Kann schon sein, aber trotzdem sollte man nicht unbedingt potentielle Fehler einbauen, wenn man es leicht vermeiden kann. Wenn man z.B. nicht nur den Vater sondern auch die Mutter abbilden will dann ändert sich eben die Strukturgrösse und die Angaben stimmen nicht mehr. Das ist eine Änderung die eigentlich recht plausibel ist. Auch bei einer Übungsaufgabe.
-
Offenbar gibt es in der Standard C-Bibliothek Funktionen, um mit binären Bäume zu arbeiten, z.B. um sie zu durchsuchen: "tsearch()", "tfind()", "tdelete()", "twalk()" und "tdestroy()".
Bitte melde dich an, um diesen Link zu sehen.
Hier das Code-Beispiel aus der man-Seite:
C
Alles anzeigen#define _GNU_SOURCE /* Expose declaration of tdestroy() */ #include <search.h> #include <stdlib.h> #include <stdio.h> #include <time.h> /* tree_example.c */ static void *root = NULL; static void * xmalloc(unsigned n) { void *p; p = malloc(n); if (p) { return p; } fprintf(stderr, "insufficient memory\\n"); exit(EXIT_FAILURE); } static int compare(const void *pa, const void *pb) { if (*(int *) pa < *(int *) pb) { return -1; } if (*(int *) pa > *(int *) pb) { return 1; } return 0; } static void action(const void *nodep, const VISIT which, const int depth) { int *datap; switch (which) { case preorder: break; case postorder: datap = *(int **) nodep; printf("%6d\n", *datap); break; case endorder: break; case leaf: datap = *(int **) nodep; printf("%6d\n", *datap); break; } } int main(void) { int i, *ptr; void *val; srand(time(NULL)); for (i = 0; i < 12; i++) { ptr = xmalloc(sizeof(int)); *ptr = rand() & 0xff; val = tsearch((void *) ptr, &root, compare); if (val == NULL) { exit(EXIT_FAILURE); } else if ((*(int **) val) != ptr) { free(ptr); } } twalk(root, action); tdestroy(root, free); exit(EXIT_SUCCESS); }Schon das kleine Beispiel kann ich kaum verstehen, und "tree2array()" sowie "array2tree()" zu schreiben, wird mir auch zu kompliziert. Das kann man auch kaum noch in so einem Forum diskutieren, weil alle auf sehr verschiedenen Kenntnisständen sind, und die meisten dann aussteigen. Ist mir auch schon in anderen C-Foren aufgefallen. Verfluchtes C.
-
Standard C-Bibliothek Funktionen
In der Tat ist eine Sache verwirrend bei C: es gibt den ISO C Standard, der die Sprache allgemein definiert, und außerdem den Posix-Standard, der Schnittstellen für Unix-Betriebssysteme definiert. tsearch ist Teil des letzteren und damit leider eher nicht portabel (z.B. kennt der Microsoft Compiler es m.W. nicht). Solange es um portable Programme geht, zählt eigentlich nur der ISO Standard, und da musst Du den binären Baum leider von Hand programmieren
. -
Ein gut gemeinter Rat: Vergiss C zu lernen auf dem Amiga!
Mir ist noch kein gutes Buch zu C auf dem Amiga über den Weg gelaufen.
Versuch zu schauen was du für Bücher zu C unter Windows findest, erlern dort die Grundlagen und dann erst schaust du dir C auf dem Amiga an.
Gute C Bücher ist auch so eine Sache. C++, die "Erweiterung" von C blende erst mal komplett aus, fang mit reinem C an. Da ein gutes Buch finden, in deutsch ist nicht so einfach. Schau dir da mehrere (online pdf Bücher) an, lies die ersten Seiten an und vergleich welches du verstehen kannst. Wenn du gar nichts verstehst, weglegen, nächstes Buch. Mit der Methode besuch dann aber auch mal deine Stadtbibliothek und einen Buchladen. Es dauert etwas bis man "sein" C-(Lern)Buch gefunden hat.
Viel Erfolg!
Dem kann ich nur zustimmen.
-