Iterativen Quelltext in Rekursiven

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
zain2
Beiträge: 10
Registriert: Mo 5. Nov 2012, 10:26
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Berlin

Iterativen Quelltext in Rekursiven

Beitrag von zain2 »

Mein Lehrer will von mir, dass ich den Quelltext rekursiv schreibe, aber ich weiß nur was das theoretisch ist, also das sich eine Prozedur selbst aufruft. Allerdings hab ich keine Ahnung wie ich das praktisch umsetzen soll.
Der Quelltext soll den größten gemeinsamen Teiler ausrechenen und funktioniert auch schon. Zur Eingabe hab ich 3 Edit Felder und ein Button zum ausführen der Prozedur.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  a,b,c:integer;
begin
a:=strtoint(Edit1.text);
b:=strtoint(Edit2.text);
   while (c>0) do
   begin
   c:=a mod b;
   a:=b;
   b:=c;
   end;
Edit3.text:=inttostr(a);
end;
 
end. 
Das ist der Quelltext. Vielen Dank schon mal im vorraus :)

MfG zain2
Die Welt geht am 31. Dezember 2099 unter, da endet der Windows Kalender...

indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Iterativen Quelltext in Rekursiven

Beitrag von indianer-frank »

Tip: Setz doch einfach die folgenden für a,b > 0 gültigen Formeln in Pascal um:
gcd(a,0) = a
gcd(a,b) = gcd(b, a mod b)

zain2
Beiträge: 10
Registriert: Mo 5. Nov 2012, 10:26
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Berlin

Re: Iterativen Quelltext in Rekursiven

Beitrag von zain2 »

Aber ich arbeite doch mit Lazarus und dort funktionieren die Pascal Codes leider nicht :/
Die Welt geht am 31. Dezember 2099 unter, da endet der Windows Kalender...

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Iterativen Quelltext in Rekursiven

Beitrag von theo »

zain2 hat geschrieben:Aber ich arbeite doch mit Lazarus und dort funktionieren die Pascal Codes leider nicht :/
Dann setze sie einfach in Lazarus um! :wink:

Kleiner Scherz. Die Sprache die Lazarus benutzt heisst Pascal.

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Iterativen Quelltext in Rekursiven

Beitrag von BeniBela »

Die Prozedur soll also umgeschrieben werden, dass sie sich rekursiv wieder aufruft um den gcd zu berechnen?

Oh, da ich habe ne ganz tolle Idee. :twisted: :lol:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  a, b: Integer;
begin
  if sender = button1 then begin
    a := StrToInt(edit1.text);
    if a < 0 then a := -a;
    b := StrToInt(edit2.text);
    if b < 0 then b := -b;
    Button1Click(tobject(pointer(cardinal((a shl 16) or b))));
  end else begin
    a := cardinal(pointer(sender)) shr 16;
    b := cardinal(pointer(sender)) and $ffff;
    if b = 0 then edit3.text := inttostr(a)
    else Button1Click(tobject(pointer(cardinal((b shl 16) or (a mod b) ))));
  end;
end;       
edit:
habe noch mal nachgedacht.
Das ist doch Mist, gcd zwischen 16 bit integers, das reicht ja für nichts ...

Nein, bei sowas braucht man 64-Bit integers, (oder zumindest 32-bit):

Code: Alles auswählen

 
procedure TForm1.Button1Click(Sender: TObject);
var
  a, b: PtrUInt;
begin
  if (self = form1) and  (sender = form1.button1) then begin
    a := StrToInt64(edit1.text);
    if a < 0 then a := -a;
    b := StrToInt64(edit2.text);
    if b < 0 then b := -b;
    TForm1(pointer(a)).Button1Click(tobject(pointer(b)));
  end else begin
    a := PtrUInt(pointer(self));
    b := PtrUInt(pointer(sender));
    if b = 0 then form1.edit3.text := inttostr(a)
    else TForm1(pointer(b)).Button1Click(tobject(pointer(a mod b)))
  end;
end;                    
 
:lol:

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Iterativen Quelltext in Rekursiven

Beitrag von pluto »

Oh, da ich habe ne ganz tolle Idee.
Ich weiß nicht so recht, ob der Lehrer sowas gemeint haben könnte.... ich glaube er meinte etwas ähliches über eine eigene Funktion. Deine Lösung ist recht Elegant. Muss ich schon sagen. den Sender einfach zu Missbrauchen. Dafür solltest du eine 1+ bekommen *G*.

Aber ob der Fragesteller das erklären kann? Weil der Lehrer wird bestimmt einige Fragen stellen zum Code.... wir können das ja mal durchspielen:
(Ich kenne die Antworten schon)
1. Entspricht der Code einen guten Programmierer Style?
2. Wozu ist der Sender eigentlich da?
3. Warum keine eigene kleine Funktion schreiben?
4. Wie bist du auf die Idee gekommen den Sender zu nutzen?
5. Was genau passiert hier eigentlich "Button1Click(tobject(pointer(cardinal((b shl 16) or (a mod b) ))));"

Gibt es weitere Fragen? *G*

Edit01:

Code: Alles auswählen

 if (self = form1) and  (sender = form1.button1) then begin
Gerade aufgefallen: Was soll dieser Vergleich? Diese Abfrage ist eigentlich überflüssig. Ich denke nicht, dass die Methode von einem anderen From als Form1 aufgerufen wird und das der Sender mal button2 sein könnte oder edit1 oder sowas.
MFG
Michael Springwald

martin_frb
Beiträge: 588
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Iterativen Quelltext in Rekursiven

Beitrag von martin_frb »

Das Problem sollte doch nicht sein diese spezielle Aufgabe rekursiv zu schreiben, sondern die generelle Frage: Wie konvertiere ich eine schleife in eine Rekursion.

Um dies zu tun muss man nicht mal wissen was die Schleife genau tut.

Code: Alles auswählen

 
while condition do
  Foo
 

Code: Alles auswählen

 
function DoFoo()
begin 
  Foo;
  if not(condition) then DoFoo;
end
 

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Iterativen Quelltext in Rekursiven

Beitrag von pluto »

Das wäre jetzt aber eine Endlos schleife...
MFG
Michael Springwald

martin_frb
Beiträge: 588
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Iterativen Quelltext in Rekursiven

Beitrag von martin_frb »

pluto hat geschrieben:Das wäre jetzt aber eine Endlos schleife...
Wieso?

Zwar sollte das "not" weg, aber endlos ist es nicht. Abbruch bedingung ist da

Code: Alles auswählen

 
function DoFoo()
begin 
  Foo;
  if (condition) then DoFoo;
end
 
alternative (Rekursion einen level tiefer)

Code: Alles auswählen

 
function DoFoo()
begin 
  if NOT(condition) then exit;
  Foo;
  DoFoo;
end
 

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Iterativen Quelltext in Rekursiven

Beitrag von pluto »

Wieso?
Zwar sollte das "not" weg, aber endlos ist es nicht. Abbruch bedingung ist da
Stimmt. Aber wie wird condition weiter gegeben bzw. was ist condition? du brauchst ja immer eine Abbruchbedienung.
MFG
Michael Springwald

martin_frb
Beiträge: 588
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Iterativen Quelltext in Rekursiven

Beitrag von martin_frb »

pluto hat geschrieben: Stimmt. Aber wie wird condition weiter gegeben bzw. was ist condition? du brauchst ja immer eine Abbruchbedienung.
Aehm, das ist doch fuer das Beispiel nicht wichtig?

"condition" ist der Term der auch in der "while" schleife als "condition" angegeben war. Genauso wie "Foo" der selbe Code wie in der schleife ist.

Es geht lediglich um die Verdeutlichung des Prinzips.

All nicht globalen variablen (all die nicht in der "loop" Version schon aus gutem Grund global sind), müssen als Parameter übergeben werden.

Wobei jede auf diese Weise erstellte Rekursion eine besondere Eigenart aufweist. Solche Rekursionen benötigen/profitieren nicht von der Tatsache das die Werte der Variablen nach jedem Rekursion Aufruf wieder zurückgesetzt werden (vom Stack zurück gelesen). Diese Feature wird ja auch in der Schleife nicht genutzt.

Die Konvertierung vor Rekursion zu Schleife kann daher schwieriger sein (obwohl das gleich Prinzip zugrunde liegt.

Antworten