I Erklärung des Problems unvollständig glauben @ Bakuriu lautet:
def fast_power(a, n):
if n == 0:
return 1
tmp = fast_power(a, n//2)
tmp *= tmp
return a*tmp if n%2 else tmp
Welche produziert. Nicht seine Reimplementierung, sondern seine Erklärung des Fehlers. Sie könnten sich davon überzeugen, indem /
mit //
in Ihrem ursprünglichen Code zu ersetzen und versuchen:
fast_power(2, 2)
es übersteigt nach wie vor den Stapel. Versuchen Sie, den Stapel zehnfach zu erweitern:
sys.setrecursionlimit(10000)
es übersteigt immer noch den Stapel. Der Grund dafür ist, dass Sie auch eine infinte Schleife haben:
if (n % 2 == 0):
return fast_power(..., 2)
Seit 2% 2 == 0, das hält einfach Rekursion für immer. Hinzufügen eines weiteren Basisfalls:
if n == 2:
return a * a
behebt das Problem. Eine vollständige Lösung:
def fast_power(a, n):
if n == 0:
return 1
# if n == 1:
# return a
if n == 2:
return a * a
if n % 2 == 0:
return fast_power(fast_power(a, n // 2), 2)
return a * fast_power(fast_power(a, n // 2), 2)
Aus diesem Grund ist Rekursion in einer nicht-rein funktionalen Sprache im Allgemeinen eine schlechte Idee, es sei denn, Sie wissen sicher, dass es nicht für eine lange Zeit ausgeführt wird. – Carcigenicate
Sie rufen die gleiche Funktion zweimal für jedes einmal aufgerufene Mal auf. Dies wird explodieren und exponentiellen Speicher nehmen, während es läuft. Bist du sicher, dass der Algorithmus richtig ist? – Carcigenicate
@Carcigenicate Der Algorithmus ist korrekt. Es benutzt die Tatsache, dass 'x^2n == (x^n)^2'. Jedoch könnte die^2 'durch eine Multiplikation ersetzt werden: 'x = fast_power (a, n // 2); return x * x' – Bakuriu