====== 7. Rekurze ======
V řešení k příkladům z cvičení v třetím týdnu byla jedna z možností, jak stanovit největší společný dělitel, pomocí funkce, která ve svém těle volala samu sebe:
# Uloha 7 z cv03 pomoci rekurze
def gcd(m,n):
if n == 0: # pri rekurzivnim volani je nutne mit ve funkci podminku, ktera ukonci funkci
return m
else: # pokud ukoncovaci podminka neni splnena, funkce zavola samu sebe s upravenymi argumenty
return gcd(n, m%n) # funkce vola samu sebe
# Uloha 7 z cv03 pomoci cyklu
def gcd(m,n):
while n != 0:
m, n = n, m%n
return m
Formálně tedy při rekurznivním volání je ve funkci s jedním nebo více argumenty podmínka na základě které se buď zavolá funkce znovu s novým argumentem, nebo se funkce ukončí
def funkce(argument):
if podminka:
funkce(novy_argument)
# vypis cisel od 0 do 9 pomoci rekurze
def vypisuj(i,N):
if i
pro pochopení, jak program prochází funkci při rekurzivním volání, a jak následně funkce opouští, si přidáme ještě jeden výpis a využijem debuger (snížíme počet čísel na 3)
# vypis cisel od 0 do 3 pomoci rekurze
def vypisuj(i,N):
if i
Úloha 1 - Nalezení maximálního čísla v seznamu
* Vezmeme první prvek v seznamu a dále zavoláme funkci pro nalezení maximalního prvku ve zbylém seznamu
* Poté porovnáme obě hodnoty a vrátíme větší hodnotu
* Pokud je délka seznamu == 1, vrátíme prvek tohoto seznamu
def najdi_maximum(seznam):
#
Úloha 2 - Pomocí rekurze implementujte funkci, která vrátí n-tý člen (indexujeme od 0) [[https://cs.wikipedia.org/wiki/Fibonacciho_posloupnost|Fibonacciho posloupnosti]] - pokuste se poté o efektivnější implementaci, která bude využívat již vypočítané hodnoty posloupnosti, které budou ukládány v globálně dostupné proměnédostupném poli - zamyslete se nad implementací jak pomocí slovníku tak pomocí pole
# Fib. posloupnost pomoci rekurze
def myfibonacci(n):
#
n = 10
Fn = myfibonacci(n)
print("F({0:d}) = {1:d}".format(n,Fn))
Úloha 3 - Pomocí rekurze napište funkci, která ze seznamu tvořeného seznamy, vrátí 1D seznam
Vstup:
[1, 2, [3, 4, [5, 7], 3], 4]
Výstup
[1, 2, 3, 4, 5, 7, 3, 4]
vstup = [[1, 2, [3, 4, [5, 7], 3], 4]]
def narovnej(vstup):
#
Úloha 4 - Pomocí rekurze najděte cestu na konec "bludiště".
* Pro jednoduchost budeme předpokládat 1D bludiště, kde index pole bude značit jednotlivá políčka od 0 do 5, kdy 0 představuje zeď a 5 je cíl. Start bude na políčku 2.
* V programu bude funkce, která zjistí, jestli se nenacházíte v cíli (konec hledání), funkce vrátí True
* Nebo ve zdi nebo na políčku, přes které jste již šli, funkce vrátí False
* Nebo zavolá samu sebe s argumentem x-1 nebo x+1 (posun na sousední poličko)
* V každém kroku ukládejte hodnoty ''%%True%%'' do pole, značícího již navštívená políčka
* Pokud je návratová hodnota funkce ''%%True%%'', uložte do pole ukazujícího správnou cestu hodnotu ''%%True%%''
===== Úlohy ve zbytku cvičení nebo na doma =====
Úloha 5 - Implementujte Euklideův algoritmus pro výpočet největšího společného dělitele pomocí rekurzivního násobení matice
Při Euklidově algoritmu (úloha v třetím cvičení) dochází k opakovanému odečítání menší z dvojice čísel od většího čísla, až dokud jsou si obě čísla rovny
Opakované odečítání dvojice čísel lze zapsat jako rekurzivní součin matic. Pro dvojici čísel ''%%m%%'' a ''%%n%%'', kde ''%%m > 1%%'': $$\begin{bmatrix} m_{k+1} \cr n_{k+1} \end{bmatrix} = \begin{bmatrix} 1 & -1 \cr 0 & 1 \end{bmatrix} \begin{bmatrix} m_{k} \cr n_{k} \end{bmatrix}$$ Pokud je ''%%m < n%%'', pak dojde k prohození jejich hodnot a vypočet pokračuje až do ''%%m == n%%''
Úloha 6 - Efektivnější varianta Euklideova algoritmu pro výpočet největšího společného dělitele pomocí maticového násobení
Opakované odečítání dvojice čísel lze zapsat jako rekurzivní součin matic. Pro dvojici čísel ''%%m%%'' a ''%%n%%'', kde ''%%m > 1%%'': $$\begin{bmatrix} m_{k+1} \cr n_{k+1} \end{bmatrix} = \begin{bmatrix} 0 & 1 \cr 1 & -(\frac{m}{n}) \end{bmatrix} \begin{bmatrix} m_{k} \cr n_{k} \end{bmatrix}$$ Pokud je ''%%m < n%%'', pak dojde k prohození jejich hodnot a vypočet pokračuje až do ''%%m == n%%''. ($\frac{m}{n}$) je zaokrouhlen dolu