Autor Beitrag
praesident118
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Sa 12.04.08 13:32 
Hallo miteinander,


wir müssen in der Schule folgendes Programm schreiben:

Der user soll einen vollständig geklammerten Infix-Term eingeben. z.b. ((3+5)*9)+(3*7)

Aus diesem soll dann mittels canvas ein Binärbaum gezeichnet werden.

Das ganze soll rekusiv erfolgen, allerdings habe ich im Moment noch nicht mal einen Ansatz.

Hättet ihr viellt. ein paar Lösungsvorschläge oder ein Beispielprogramm (z.B. Welche Parameter sollte ich verwenden?) ?


Ich muss aber noch dazu sagen, dass wir noch keine Klassen behandelt haben.


Wäre euch für eure Hilfe sehr Dankbar

mfg
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 15:26 
Hi,

Wo hapert es denn? Zur Stringverarbeitung, siehe r2c2.weingut-rehn.de...itung_mit_Delphi.htm .

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Sa 12.04.08 18:29 
Hm, diese Aufgabe würde ich in mehre Teile zerlegen... eigentlich in 2 :roll:

1. String parsen
2. Ausgeben

Erstmal brauchst du ein Datenformat, dass den Baum hält. Irgendwas wie
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
PLeaf = ^TLeaf;
TLeaf = record
  Operation: (ltValue, ltAdd,ltSubtract,ltDivide,ltMultiply);
  Op1,Op2: PLeaf;
  Value: integer;
end;

So, da müssen deine Daten rein. Die Struktur dürfte klar sein: es wird gespeichert, welche Art dieser Knoten ist. Wenn er eine Rechenoperation ist, dann sind die Operatoren wieder als Leaf-Objekte in Op1 und Op2 gespeichert. Ist der Knoten ein Wert (Operation = ltVlaue), dann steht selbiger in Value.

Du musst also rekursiv immer an Operatoren trennen und mit 'links' und 'rechts' genauso verfahren, bis nur noch einfache Werte drin stehen. Diese kommen dann in Value-Knoten.

Darstellen kann man das dann auch relativ einfach, einfach vom Root nach unten durchgehen und ausgeben. Auch wenn ich kein Canvas, sondern ein TTreeView verwenden würde, aber warum einfach, wenn's auch kompliziert geht...

Hoffe mal das dir das als Denkanstoß hilft. Irgendwann wollte ich das auch mal machen, hatte damals aber die Idee so nicht. Ich glaube ich schreibe auch mal ein kleines Beispielprogramm...

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 19:36 
user profile iconMartok hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
PLeaf = ^TLeaf;
TLeaf = record
  Operation: (ltValue, ltAdd,ltSubtract,ltDivide,ltMultiply);
  Op1,Op2: PLeaf;
  Value: integer;
end;


Hi,

Sie haben sich noch nicht mit Klassen beschäftigt, ob sie dann Pointer schon kennen :?:

Zur Erklärung: Ein Pointer wird durch ein Dach(^) gekennzeichnet und enthält eine Speicheradresse, über die auf den entsprechenden Speicher zugegriffen werden kann. Pointer(zu Deutsch: Zeiger) werden von Delphi oft implizit verwendet, d.h., wenn du eine Variable als TLeaf deklarierst, mach Delphi oft Pointer daraus.

Zum Umgang mit Pointern: Der Operator(Operatoren sind z.B. +, - oder *) "@" liefert die Speicheradresse der nachstehenden Variable. Bei der Deklaration von Pointern kommt das Dach danach(MyPointer^). Verwendest du den Pointer nun, so wird zunächst einmal auf die Speicheradresse zugegriffen, z.B. MyPouinter := @MyObject. Willst du nun auf den Speicher, statt auf die Speicheradresse, zugreifen, so liefert ein Dach nach dem Pointer(MyPointer^) den Speicher, auf den die Adresse/der Pointer zeigt.

Was Martok also vorschlägt ist, dass z.B. (3 + 4) * (6 + 2) als eine Operation angesehen wird, die aus den Operationen 3 + 4 und 6 + 2 besteht. Das Ausrechnen eines Terms würde dann über eine Methode verlaufen, die einen TLeaf-Record als Parameter verwendet und, wenn er wiederum aus zwei Operationen besteht, sich selbst(rekursiv also) wieder aufruft, um das Ergebnis seiner Einseloperationen zu erhalten.

Wenn ihr noch keine Pointer behandelt habt, lass die deklaration als Pointer einfach weg:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
TLeaf = record
  Operation: (ltValue, ltAdd,ltSubtract,ltDivide,ltMultiply);
  Op1,Op2: TLeaf;
  Value: integer;
end;


Delphi behandelt diese Variable dann implizit als Pointer.

Habt ihr euch schon mit nil beschäftigt? Das ist ein Pointer auf eine leere Speicheradresse, also ins nichts.

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Sa 12.04.08 20:14 
Naja, die Aufgabe sah mir nach einem Paradebeispiel für Binary Trees aus, und die werden meistens verpointert^^

Lassen wir den praesidenten mal was dazu sagen ;)

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."