Hilfe bei Rekursiver Funktion

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Hartmannsgruber
User
Beiträge: 89
Registriert: Mittwoch 15. Januar 2014, 22:30
Wohnort: Bad Kötzting
Kontaktdaten:

Servus Forum,

ich habe mich an meine erste vermutlich rekursive Funktion getraut.
nun habe ich folgendes geschrieben:

Code: Alles auswählen

from more_itertools import pairwise

def folge(l1, muster, durchgang, startpunkt):
    for i, j in pairwise(l1[startpunkt: -1]):
        print(f"i:{i}, j:{j}")
        print(f"durchgang: {durchgang}, muster[durchgang]: {muster[durchgang]}")
        if i + j == muster[durchgang]:
            print(f"{i} + {j} = {muster[durchgang]}")
            startpunkt = l1.index(j)

            if durchgang < len(muster)-1:
                durchgang += 1
            else:
                durchgang = 0
            
            print(f"j: {j}, index: {l1.index(j)}")
            print(f"durchgang: {durchgang}")
            print("-"*10)
            folge(l1, muster, durchgang, startpunkt)
        else:
            durchgang = 0
            
zahlenfolge = [11, 12, 13, 14, 15, 16, 17]
muster = [27, 29, 31]

folge(zahlenfolge, ergebnissreihe, 0, 0)
Wenn ich nun die Funktion aufrufe, arbeit sie brav durch, bis sie den Wert mit j = 16 erreicht.
Ab hier macht sie total komisches zeug. Ich erhalte folgende ausgabe:

Code: Alles auswählen

i:11, j:12
durchgang: 0, muster[durchgang]: 27
i:12, j:13
durchgang: 0, muster[durchgang]: 27
i:13, j:14
durchgang: 0, muster[durchgang]: 27
13 + 14 = 27
j: 14, index: 3
durchgang: 1
----------
i:14, j:15
durchgang: 1, muster[durchgang]: 29
14 + 15 = 29
j: 15, index: 4
durchgang: 2
----------
i:15, j:16
durchgang: 2, muster[durchgang]: 31
15 + 16 = 31
j: 16, index: 5
durchgang: 0
----------
i:15, j:16
durchgang: 2, muster[durchgang]: 31
15 + 16 = 31
j: 16, index: 5
durchgang: 0
----------
i:14, j:15
durchgang: 1, muster[durchgang]: 29
14 + 15 = 29
j: 15, index: 4
durchgang: 2
----------
i:15, j:16
durchgang: 2, muster[durchgang]: 31
15 + 16 = 31
j: 16, index: 5
durchgang: 0
----------
i:15, j:16
durchgang: 2, muster[durchgang]: 31
15 + 16 = 31
j: 16, index: 5
durchgang: 0
----------
Ich glaube zwar, dass es nur sehr einfach ist, aber was ist der Fehler??? :shock:
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Um zu erkennen, was "komisches Zeug" ist, müsste man wissen, was die Funktion überhaupt tun soll, für mich ist da alles komisch.
Hartmannsgruber
User
Beiträge: 89
Registriert: Mittwoch 15. Januar 2014, 22:30
Wohnort: Bad Kötzting
Kontaktdaten:

Einen praktischen Sinn hat die Funktion nicht.
Für mich war es das erste mal das ich mich mit solch einer Rekursiven Funktion beschäftigt habe.
Daher habe ich um diese Art von Funktion zu verstehen ein kleines Beispiel geschrieben.

Der Sinn den ich mir gedacht habe wäre folgedender:
Die Funktion untersucht ein Liste auf das Vorkommen einer bestimmten Zahlenfolge.
Wird die erste Zahl aus dem Muster in der Zahlenfolge gefunden, so wird dieser gefolgt, ob
alle Zahlen des Musters auftachen, oder es wieder bei der ersten Zahl des Musters begonnen.
Hartmannsgruber
User
Beiträge: 89
Registriert: Mittwoch 15. Januar 2014, 22:30
Wohnort: Bad Kötzting
Kontaktdaten:

Ich konnte das Problem selbst lösen.
Das mit der rekursiven Funktion funktioniert in diesm Fall nicht.
Ich habe es mit zwei for Schleifen gelöst.

Code: Alles auswählen

def pruefe_muster(wert1, wert2, ergebnis):
    if wert1 + wert2 == ergebnis:
        return True

for i, j in pairwise(a):
    durchgang = 0
    print(f"i:{i}, j:{j}")
    print(f"durchgang: {durchgang}, ergebnissreihe[durchgang]: {ergebnissreihe[durchgang]}")
    print("-"*10)

    if pruefe_muster(i, j, ergebnissreihe[durchgang]):
        print(f"{i} + {j} = {ergebnissreihe[durchgang]}")

        for k,l in pairwise(a[a.index(i):]):
            print(k,l)

            if pruefe_muster(k, l, ergebnissreihe[durchgang]):
                print("ok")

                if durchgang < len(ergebnissreihe)-1:
                    durchgang += 1
                else:
                    break
            else:
                break
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

`pruefe_muster` liefert entweder explizit True oder implizit None zurück. Das sollte nicht sein.
Wenn man eine Bedingung hat, dann kann man die auch direkt zur Rückgabe benutzen:

Code: Alles auswählen

def pruefe_muster(wert1, wert2, ergebnis):
    return wert1 + wert2 == ergebnis
durchgang ist am Anfang immer 0. Klarer wäre es, dafür auch 0 zu benutzen.

`index` funktioniert nicht so, wie es soll, wenn in `a` ein Wert doppelt vorkommt. Sollte das ausgeschlossen sein, wäre es dennoch besser, den Index explizit zu zählen.
In der inneren for-Schleife zählst Du durchgang explizit, per zip könnte man das aber vermeiden.

Code: Alles auswählen

for index, (i, j) in enumerate(pairwise(a)):
    print(f"i:{i}, j:{j}")
    print(f"durchgang: 0, ergebnissreihe[0]: {ergebnissreihe[0]}")
    print("-"*10)

    if pruefe_muster(i, j, ergebnissreihe[0]):
        print(f"{i} + {j} = {ergebnissreihe[0]}")

        for ergebnis, (k,l) in zip(ergebnisreihe, pairwise(a[index:])):
            print(k, l, ergebnis)
            if not pruefe_muster(k, l, ergebnis):
                break
            print("ok")
Die Prüfung bei durchgang 0 wird jetzt noch zweimal vorgenommen, auf einen Vergleich kann man verzichten:

Code: Alles auswählen

for index, (i, j) in enumerate(pairwise(a)):
    print(f"i:{i}, j:{j}")
    print(f"durchgang: 0, ergebnissreihe[0]: {ergebnissreihe[0]}")
    print("-"*10)

    for ergebnis, (k,l) in zip(ergebnisreihe, pairwise(a[index:])):
        print(k, l, ergebnis)
        if not pruefe_muster(k, l, ergebnis):
            break
        print("ok")
Jetzt wird aber i und j gar nicht mehr gebraucht.

Code: Alles auswählen

for index in range(len(a)-len(ergebnisreihe)):
    for ergebnis, (k,l) in zip(ergebnisreihe, pairwise(a[index:])):
        if not pruefe_muster(k, l, ergebnis):
            break
    else:
        print(f"Muster bei Index {index} gefunden.")
Antworten