Алгоритм быстрого возведения в степень, два подхода, в чем разница?
Не совсем понимаю в чём существенная разница в реализации этих двух алгоритмов?
def pow(a, n):
if n==0:
return 1
elif n%2 == 0:
return pow(a, n//2)**2
else:
return pow(a, n-1)*a
def pow2(a, n):
if n == 0:
return 1
elif n%2 == 1:
return pow2(a,n-1)*a
else:
return pow2(a**2, n//2)
Ответы (1 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
Единственное существенное различие - разный порядок операций: pow(a, n//2)**2 и pow2(a**2, n//2). Это приводит к различиям в производительности. Пример:
import time
def elapsed(f):
start = time.perf_counter()
r = f()
finish = time.perf_counter()
return finish - start, r
def pow(a, n):
if n==0:
return 1
elif n%2 == 0:
return pow(a, n//2)**2
else:
return pow(a, n-1)*a
def pow2(a, n):
if n == 0:
return 1
elif n%2 == 1:
return pow2(a,n-1)*a
else:
return pow2(a**2, n//2)
def test(a, n):
t1, r1 = elapsed(lambda: pow(a, n))
t2, r2 = elapsed(lambda: pow2(a, n))
assert r1 == r2
print(f'{a} ** {n}', f'{t1:5.2f}', f'{t2:5.2f}')
def main():
for p in range(20, 30):
n = 2 ** p - 1
a = 3
test(a, n)
main()
$ python difference.py 3 ** 1048575 0.09 0.22 3 ** 2097151 0.26 0.66 3 ** 4194303 0.77 2.01 3 ** 8388607 2.32 6.12 3 ** 16777215 7.01 18.53 3 ** 33554431 21.18 56.44
Вторая реализация на этих примерах примерно в два с половиной раза медленнее первой.