Potrzebuję funkcji, która pobiera n i zwraca 2 n - 1 . Brzmi to dość prosto, ale funkcja musi być rekurencyjna. Do tej pory mam tylko 2 n :
def required_steps(n):
if n == 0:
return 1
return 2 * req_steps(n-1)
Ćwiczenie stwierdza: „Możesz założyć, że parametr n jest zawsze dodatnią liczbą całkowitą i jest większy od 0”
1 << n
nie mogą się przepełnić. Wydaje się, że jest to ćwiczenie polegające na wynalezieniu sposobu rozpadu(1<<n) - 1
na wiele etapów, być może ustawienie każdego z bitów pojedynczo, jak pokazują niektóre odpowiedzi.def fn(n): if n == 0: return 1; return (2 << n) - fn(0); # technically recursive
C:\MyFolder
Odpowiedzi:
2**n -1
to także 1 + 2 + 4 + ... + 2 n-1, które można przekształcić w jedną funkcję rekurencyjną (bez drugiej, aby odjąć 1 od potęgi 2).Wskazówka : 1 + 2 * (1 + 2 * (...))
Rozwiązanie poniżej, nie patrz, czy chcesz najpierw wypróbować podpowiedź.
Działa
n
to, jeśli jest gwarantowane, że jest większe od zera (tak jak faktycznie obiecano w opisie problemu):Bardziej niezawodna wersja obsługiwałaby również wartości zerowe i ujemne:
(Dodanie czeku dla liczb całkowitych jest pozostawione jako ćwiczenie).
źródło
required_steps(0)
teraz powoduje nieskończoną rekurencję2^0 - 1
== 0. Dodaj kolejnąif
dla tego przypadku.int
, nie wiemy, co robić, gdy n <0. Oblicz? Zgłaszać błąd? Zwrócić 0? W takim przypadku możemy wykonać tylko funkcję częściową (zdefiniować ją dla rzeczy, które wiemy, jaki jest wynik).0
i wykorzystujen - 1
podproblem. Domena liczb naturalnych wydaje się być dobrze dopasowana.Aby rozwiązać problem z podejściem rekurencyjnym, musisz dowiedzieć się, w jaki sposób możesz zdefiniować funkcję z danym wejściem w kategoriach tej samej funkcji z innym wejściem. W takim przypadku
f(n) = 2 * f(n - 1) + 1
możesz wykonać:po to aby:
wyjścia:
źródło
Możesz wyodrębnić naprawdę rekurencyjną część do innej funkcji
Lub możesz ustawić flagę i określić, kiedy odjąć
źródło
Używając dodatkowego parametru dla wyniku,
r
-Możesz także napisać, używając bitowego przesunięcia w lewo,
<<
-Dane wyjściowe są takie same
źródło
else
klauzuli w żadnej z funkcjir * 2
nar << 1
„w ogóle nieczytelna”? 😂n
razy, a następnie odejmuje 1. wydaje się jeszcze mniej elegancki wtedy konieczne, chociaż cała sprawa jest ćwiczeniem w nieskuteczności vs.(1<<n) - 1
.Miej symbol zastępczy, aby zapamiętać oryginalną wartość n, a następnie dla pierwszego kroku, tj.
n == N
Powrotu2^n-1
źródło
Jednym ze sposobów uzyskania przesunięcia „-1” jest zastosowanie go w zwrocie z pierwszego wywołania funkcji za pomocą argumentu o wartości domyślnej, a następnie jawne ustawienie argumentu przesunięcia na zero podczas wywołań rekurencyjnych.
źródło
Oprócz wszystkich wspaniałych odpowiedzi podanych wcześniej, poniżej pokażę jego implementację z funkcjami wewnętrznymi.
Zasadniczo przypisuje globalną wartość od n do k i rekursuje ją za pomocą odpowiednich porównań.
źródło