2010-09-15 22 views
5

Ich versuche gerade, mich mit dem Lernen von Python zu beschäftigen, und ich bin bei rekursiven Funktionen zu etwas abgestanden. In Think Python, ist eine der Aufgaben eine Funktion zu schreiben, die a, wenn Zahl eine Potenz von Nummer b unter Verwendung der folgende Definition bestimmt:Warum gibt meine rekursive Funktion None zurück?

„eine Zahl, ein, eine Potenz von b, wenn es ist durch b teilbar und a/b ist eine Potenz von b. Schreiben Sie eine Funktion namens is_power, die die Parameter a und b annimmt und True zurückgibt, wenn a eine Potenz von b ist. "

Der aktuelle Stand meiner Funktion:

def isPower(a,b): 
    return a % b == 0 and (a/b) % b == 0 

print isPower(num1,num2) 

Wie es ist, das das Ergebnis produziert ich erwarte. Das Kapitel konzentriert sich jedoch auf das Schreiben von rekursiven Funktionen, um die Redundanz zu reduzieren, und ich bin mir nicht ganz sicher, wie ich das letzte "(a/b)% b == 0" in eine Rekursion umwandeln kann. Ich habe versucht:

def isPower(a,b): 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 

Aber das gibt nur keine zurück.

Was ist der richtige Weg, um diese Funktion zu rekrutieren?

+3

Sie, dass die Bedeutung des ‚/‘ Operator in Python hat sich geändert: Hütet 3+, von der Rückgabe einer Ganzzahl bis zur Rückgabe eines Floats, damit Ihr Code nicht mehr funktioniert. Ändern Sie stattdessen zu '//', was immer einen int zurückgibt. –

+2

Beachten Sie, dass Ihr erster Versuch nicht prüft, ob a eine Potenz von b ist, es prüft, ob a ein Vielfaches von b^2 ist. versuch isPower (12,2), es würde True zurückgeben. – Javier

+0

Nur so heißt es, deine erste Version von isPower ist kaputt - es wird nur angezeigt, ob 'a' ein Vielfaches von' b^2' ist. Es wird zum Beispiel für 'isPower (2, 1)' true zurückgegeben, was niemals wahr sein sollte. Zu diesem Zweck sollten Sie sicherstellen, dass jede rekursive Version überprüft, ob '(b == 1 && a! = 1)' bevor es fortfährt, oder es entweder in einer Endlosschleife stecken bleibt oder die falsche Sache zurückgibt. – cHao

Antwort

3

Sie einen Basisfall zu vergessen, wenn a == 1:

def isPower(a,b): 
    if a == 1: 
     return True 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 
    else 
     return False 

Doch diese hat einige andere Probleme - wenn a 0 ist, wird es nie enden und wenn b 0 ist, dann erhalten Sie eine Division durch Null.

Hier ist eine ausführliche Lösung, die so weit wie ich für alle ganzzahligen Kombinationen funktionieren kann sagen:

def isPower(a,b): 
    if a == 0 or b == 0: 
     return False 
    def realIsPower(a, b): 
     if a == 1: 
      return True 
     elif a%b != 0: 
      return False 
     elif realIsPower((a/b), b): 
      return True 
     else: 
      return False 
    return realIsPower(a, b) 

EDIT: Mein Code für Fälle funktioniert nicht, wenn a und b negativ ist. Ich vergleiche jetzt ihre absoluten Werte.

EDIT2: Dumm mich, x^0 == 1, also a == 1 sollte IMMER True zurückgeben. Das bedeutet auch, dass ich vor der Rekursion kein a mit b vergleichen muss. Danke @Javier.

+0

Vielen Dank. Dies verdeutlichte genau was ich vermisst habe. Nachdem ich etwas mehr damit herumgebastelt hatte, hatte ich eine maximale Rekursionsschleife erreicht, konnte aber nicht herausfinden, wie ich sie stoppen konnte. Ich nehme an, dass ich davon ausgehe, dass der Dolmetscher es wissen würde. Ich wollte nur, dass es aufhört, nachdem es sich selbst noch einmal gespielt hat. Jetzt verstehe ich, dass, wenn ich einen rekursiven Aufruf schreibe, einer der Tests, um diesen ELIF-Zweig überhaupt zu erreichen, in der Lage sein muss, ihn zu stoppen. Dies war nur eine Übungsfunktion, also wäre es für eine Basis von 1 gut gewesen, aber danke, dass du alles getan hast, um zu helfen! – bobby

+1

Hey, ich bin froh, dass ich helfen konnte! Denken Sie immer daran, dass für alle rekursiven Funktionen zwei Dinge erforderlich sind: ein Basisfall und ein rekursiver Aufruf. Manchmal (wie in diesem Fall) gibt es mehr als einen Basisfall. –

2

Sie benötigen einen zusätzlichen Fall, denn wenn beide conditionals return false

def isPower(a,b): 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 
    else 
     return False 
+0

Ich denke, du meinst ein% b, nicht ein & b – Bob

+0

Dies wird immer false zurückgeben. –

+0

Sie müssen eigentlich auch den Basisfall berücksichtigen. Ich habe gerade den Tippfehler entfernt. –

1
def isPower (a,b): 
    return a==1 or (a!=0 and b!=0 and b!=1 and isPower((a/b),b)) 
+0

Dies wird immer true zurückgeben, wenn a anfänglich 1 ist, aber das ist nur der Fall, wenn b 1 oder -1 ist. –

+0

Danke für Ihre Hilfe, Javier. Deine und Nikis Antworten waren genau das, was ich brauchte, um in meinen Kopf zu klicken. Ich verstehe die Bedeutung von Scaffolding und schreibe übertriebenen Code mit vielen Tests auf dem Weg, aber sobald ich mit der Syntax und Logik vertraut bin, möchte ich in der Lage sein, den kürzesten Code zu produzieren, der den gleichen Effekt erzeugt. Diese Antwort war großartig zu sehen, wie Nikis Antwort als One-Liner für zukünftige Referenz aussieht. Schade, ich kann nicht zwei Antworten bekommen! – bobby

+0

@ Niki Yoshiuchi: 1 ist eine Macht einer beliebigen Zahl (x^0 = 1 für jedes x) – Javier

0

dies versuchen,

def ispower(a,b): 
    if b==a: 
    return True 
    elif a<b: 
    return False 
    else: 
    return ispower(a*1.0/b, b) 
+0

eine Erklärung würde diese Antwort helfen – dove

1

Hier ist mein Code. Von dem, was ich getestet habe, funktioniert es:

def ispower(a, b): 

    if b == 1 or b == 0: 
     return False 
    if b <= 0 or a <= 0: 
     return False 
    if a % b == 0: 
     if ((a/b)/b) == 1: 
      return True 
     else: 
      return ispower(a/b, b) 
    else: 
     return False 
     print ispower(-10, 2) 
0
def is_power (a, b): 

    if a == 1: 
     return True 
    if a == 0 and b == 0: 
     return True 
    if a == 0 or b == 0: 
     return False 
    if a%b != 0: 
     return False 
    elif is_power ((a/b), b): 
     return True 
0

meine Antwort hier, es ist ein wenig sauberer:

def is_power(a, b): 
    if a == 1: 
     return True 
    if a == 0 or b == 0: 
     return False 
    if a % b == 0 and is_power(a/b, b): 
     return True 
    else: 
     return False 
Verwandte Themen