Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Rekursion


Tommy82 - Mo 23.09.02 19:23
Titel: Rekursion
Hi, ein kleines problem mal wieder

Im Informatikunterricht haben wir heute Das Thema Rekursion durchgenommen. Nun sollen wir eine Aufgabe zu Hause machen. :roll:

Man muss ein Wort eingeben und es dann rückwärts wieder ausgeben lassen. und das mit hilfe von rekursion !!
also muss man jeden Buchstaben einzeln einlesen und wenn '#' ist, dann ist das Wort komplett. Es soll also folgendermaßen aussehen :

Quelltext
1:
2:
3:
4:
5:
6:
PROCEDURE Worteingabe;
BEGIN
readln(Buchstabe)
  IF buchstabe <> '#' THEN Worteingabe
  else
  ........

So in etwa soll es aussehen.
Wie kann ich jetzt aber die ganzen Buchstaben, die er bei jedem Neustart der Procedure einließt, zu einem Wort zusammenbinden ?
Dann soll er aber auch wieder die Buchstaben von diesem Wort einzeln auslesen können, denn er soll danach das Wort rückwärts schreiben (will unser IF-Lehrer so) :!:


Delete - Mo 23.09.02 20:03

Ich kann mich nicht erinnern solch eine Hausaufgabe bekommen zu haben.

*bing* Aaah, DU sollst das machen. Ich denke, wir sind nicht dazu da dir deine Hausaufgaen zu machen.

Zeigt doch mal, was du schon hast, dann können wir darüber diskutieren.


Tommy82 - Mo 23.09.02 22:08
Titel: Rekursion
Ihr sollt ja auch nicht meine hausaufgaben machen, ihr sollt mir nur zeigen, wie das geht, also mir sagen, wie ich das Wort zusammenbringen kann usw. Aber nicht den ganzen Quelltext


Delete - Mo 23.09.02 22:19

N azeig doch mal was du bisher hast ud wo du stecken bleibst bzw. was nicht funktioniert. Du müßtest es doch schon probiert haben, sonst würdest du ja hoffentlich nicht fragen.


Anonymous - Di 24.09.02 14:47

War schon fast richtig, zumindest der Rekursivteil. Etwas nachgedacht und man kommt selbst drauf.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure Worteingabe;
begin
  ReadLn(Buchstabe);
  if Buchstabe <> '#' then
  begin
    Wort := Buchstabe + Wort;
    Worteingabe;
  end;
end;


Allerdings wartest du auf einzelne Buchstaben und nicht auf Wörter. Dafür ist ReadLn nicht die optimale Wahl. Es sollte eine Abfrage für einen Buchstaben sein. Bei ReadLn kannst du mehr als nur einen Buchstaben eingeben. ReadKey wäre besser, gibt es aber glaube ich nicht mehr.

Deshalb solltest du bei der Eingabe zumindest drauf achten, daß nur ein Buchstabe durchkommt. Das könntest du mit einer Abrage machen.


Quelltext
1:
2:
3:
4:
5:
procedure Worteingabe;
begin
  ReadLn(Buchstabe);
  if Length(Buchstabe) > 1 then Buchstabe := Copy(Buchstabe, 1, 1); 
  ...


Tommy82 - Di 24.09.02 14:52
Titel: also gut
so weit, so gut, was eigentlich fehlt (und auch das problem bei dieser Aufgabe ist) ist, wie kann ich das Wort nun noch auseinandernehmen, so dass ich dann jeden Buchstaben einzeln erkennen kann. denn schließlich soll er dann ja das Wort wieder rückwärts schreiben. bei diesem Problem komme ich einfach nicht weiter. :?:


GPF - Di 24.09.02 15:17

Die einzelnen Zeichen einer Zeichenkette kannst Du mit dem Arrayoperator [] ansprechen. Dazwischen gibst Du den entsprechenden Index - beginnend bei 1 - an. Über die Funktion Length ermittelst Du die Länge der Zeichenkette.

Um Beispielsweise einen String zu zerlegen und Zeichen für Zeichen an einen anderen anzufügen ein kleines Beispiel wie Du eine Zeichenkette umkehren kannst, die mit einer einfachen for-Schleife arbeitet. Für die Rekursion bist Du zuständig:


Quelltext
1:
2:
3:
4:
5:
6:
7:
function ReverseString(const SourceString: string): string;
var i:integer;
begin
  Result:='';
  for i:= Length(SourceString) downto 1 do
    Result:=Result+SourceString[i];
end;


aogwaba - Di 24.09.02 21:48

Ähm...

@Popov:
ne rekursive Prodecure mit globlen Variablen, meinst du das klappt so?

cu
waba


Tommy82 - Mi 25.09.02 14:59
Titel: letztes
hi, ich habe das Programm jetzt soweit fertig.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
PROCEDURE Worteingabe;
BEGIN
 Buchstabe := readkey;
 If Buchstabe <> '#' THEN BEGIN
  Wort := Buchstabe + Wort;
  Worteingabe;
 END
ELSE
 CLRSCR;
 GOTOXY(10,20); WRITELN(Wort);
 READLN;
END;

So, jetzt besteht nur noch ein problem. Wenn ich readkey nehme, dann sehe ich die eingabe nicht auf dem Bildschirm und wenn ich Readln(buchstabe) nehme, dann kann ich mehrere Buchstaben eingeben(und er nimmt aber nur den ersten, da man readln mit return bestätigen muss).
Wie bekomme ich es jetzt hin, dass er den ersten Buchstaben zeigt und dass ich keinen weiteren während des Durchlaufens dieser procedure eingeben kann (sondern erst bei wiederaufrufung soll er den zweiten eingeben , dann den dritten usw)


wwerner - Mi 25.09.02 15:25


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure Worteingabe;

begin
  Buchstabe := readkey;
  if Buchstabe <> '#'
  then 
    begin
      write(Buchstabe); //Benutzerinfo
      Wort := Buchstabe + Wort;
      Worteingabe;
    end
  else
    CLRSCR;

  GOTOXY(10,20); 
  WRITELN(Wort);
  READLN;
end;


aogwaba - Mi 25.09.02 19:05

Hi Tommy82!

Deine Aufgabe:
Zitat:
Man muss ein Wort eingeben und es dann rückwärts wieder ausgeben lassen. und das mit hilfe von rekursion !!


Hört sich so an, als sollte die Ausgabe rekursiv geschehen.

cu
waba


Delete - Mi 25.09.02 19:07

aogwaba hat folgendes geschrieben:

Hört sich so an, als sollte die Ausgabe rekursiv geschehen.

Das erste Posting in diesem Thread hast du nicht gelesen oder? :roll:


aogwaba - Mi 25.09.02 19:19

Zitat:
Das erste Posting in diesem Thread hast du nicht gelesen oder?

Mehrmals. Habs wohl falsch inerpretiert, wie immer. ;)

cu
waba


Tommy82 - Mi 25.09.02 21:05
Titel: Danke
ich habe das problem schon gelöst, vielen Dank für eure hilfe


Anonymous - Do 26.09.02 01:07

aogwaba hat folgendes geschrieben:
Ähm...

@Popov:
ne rekursive Prodecure mit globlen Variablen, meinst du das klappt so?

cu
waba


Wo ist das Problem? Was soll nicht klappen?


aogwaba - Do 26.09.02 18:26

Hi Popov!

Technisch klappt das. Finde das nur bisschen unsauber mit den globalen
Variablen und das das keine rekursive-Funktion ist.

cu
waba


Anonymous - Do 26.09.02 21:36

@aogwaba

Eigentlich glaube ich zu wissen wann man globale Variablen einsetzen sollte und wann nicht. In einem andrem Forum brach der größte Streit seiner Geschichte aus und man hat mir (zumindest hab ich das Gefühl) körperliche Gewalt angedroht, weil ich mich geweigert habe eine globale Variable zu nehmen. Ich hab TBitmap Objekt-Variable jedes mal neu erstellt und immer wieder freigegeben. Andere meinten ich solle die Variable permanent im Speicher halten, weil es besser ist und 2,5 MB Verlust bei den heutigen Speicherpreisen kein Problem sind. Ich bin deswegen als ein unfähiger Programmier bezeichnet worden - weil ich keine globale Variable benutzen wollte. :twisted: Spaß beiseite. Ist zwar passiert, aber ich nehme das inzwischen von der lustigen Seite. Man kann aber sehen wie sehr globale Variablen die Gemüter erhitzen können.

Zu meinem Beispiel: du hast recht - das Beispiel hätte man besser machen können. Allerdings kenne ich die Kenntnisse von Tommy82 nicht. Kann sein, daß er ein Profi ist. Kann sein, daß er ein Anfänger ist. Für den Fall, daß er ein Anfänger ist wollte ich kein Beispiel machen welches so kompliziert ist, daß er ihn nicht verstehen würde. Ich hab keine Lust gehabt ein Beispiel zu machen das ich später erklären müßte. Ich finde es auch nicht schlimm, daß Anfänger mit globalen Variablen arbeiten. Ist zumindest keine Sache die man sich später schwer abgewöhnen kann. Kommt Zeit kommen lokale Variablen. Der Sinn wieso man keine globale Variablen nehmen sollte ist der, daß der Code später schwer lesbar wird. Ich glaube nicht, daß in diesem Schulbeispiel diese Gefahr besteht.

:D :D :D


Tommy82 - Fr 27.09.02 15:36
Titel: Anfänger
Meine kenntnisse liegen noch im Anfängerbereich. Dieses Quelltext habe ich verstanden. Wie sähe es denn in etwa aus, wenn ich ein Profi wäre ?


Anonymous - Sa 28.09.02 16:46

Wenn du ein Profi wärst, dann würde es nicht viel anders aussehen. Es ist ja kein Programm, es ist nur eine Prozedur. Wenn du aber ein Profi wärst, dann hätte ich in dem Beispiel kein ReadLn und kein ReadKey benutzt. Eigentlich hat Delphi kein ReadKey mehr. Mit den beiden Funktionen hab ich schon Jahre nicht mehr gearbeitet. Delphi bietet da elegantere Möglichkeiten. Anderseits, mit den eleganteren Möglichkeiten von Delphi wäre die Sache mit der rekursiven Eigabe etwas problematischer. Mir wäre da aber etwas eingefallen. Weiter. Da du bei der Eingabe nur an einem Buchstaben interessiert bist, hätte ich für die Eingabe nicht einen String, sondern ein Char benutzt. Das würde sich zwar mit ReadLn beißen, bei ReadKey gäbe es da keine Probleme. Weiterhin wäre die Variable Buchstabe geradezu prädestiniert für eine lokale Variable.

Aber zurück zum wesentlichen. Die Variable Wort hätte ich weder als globale noch als lokale Variable deklariert. Ich hätte sie als Parameter übergeben, z.B.:

procedure Worteingabe(var Wort);

Wie du siehst sind es nur Kleinigkeiten. Und es gibt noch viel mehr Kleinigkeiten die man da einbauen könnte. Hab aber keine Lust mir da Gedanken zu machen. Das Problem ist, daß das ganze Beispiel ein TP Beispiel ist. Man muß bei dem Beispiel zurückdenken.


Tommy82 - Sa 28.09.02 20:04
Titel: Übung macht den Meister
Cool, dann ist ja der weg zum Profi nicht mehr weit

:roll:


Anonymous - Sa 28.09.02 22:06

Dann viel Spaß auf dem Weg