190 likes | 377 Views
Python - rekurzija. Zgledi. Izpiši števila od 1 do n. Nerekurzivno def izpis(n): for i in range(1, n + 1): print (i). "Šefovsko razmišljanje". Denimo, da imamo nekoga, ki zna izpisati števila od 1 do n-1 Ali: imamo funkcijo izpisDoNminus1 def izpis(n): izpisDoNminus1(n – 1)
E N D
Python - rekurzija Zgledi
Izpiši števila od 1 do n • Nerekurzivno def izpis(n): for i in range(1, n + 1): print(i)
"Šefovsko razmišljanje" • Denimo, da imamo nekoga, ki zna izpisati števila od 1 do n-1 • Ali: imamo funkcijo izpisDoNminus1 • def izpis(n): • izpisDoNminus1(n – 1) • print(n) • Kako bi bila videti funkcija izpisDoNminus1? • Enako kot izpis! • def izpis(n): • izpis(n – 1) • print(n)
Za n = 3 • klic: izpis(3) • klic: izpis(2) • klic: izpis(1) • ... • po opravljenem klicu izpis(1) se izpiše 2 • po opravljenem klicu izpis(2) se izpiše 3 • … klic izpis(0), pod njo bi sledil izpis(-1), itd. • vsak klic funkcije delo prelaga dalje. • Če delo samo prelagamo, ne bo nikoli narejeno! • Gordijski vozel prerežemo tako, da končno nekdo nekaj res naredi.
Izpis(1) • Ne bo več prelagal dela, ampak res izpisal • def izpis(n): • if n == 1: • print(1) • return • izpis(n - 1) • print(n)
Dogajanje • klic: izpis(3) • zaustavitveni pogoj ni izpolnjen, zato: • klic: izpis(2) • zaustavitveni pogoj ni izpolnjen, zato: • klic: izpis(1) • zaustavitveni pogoj je izpolnjen • izpišemo 1 • vrnemo se iz klica izpis(1) • vrnili smo se iz klica izpis(1) • izpišemo 2 • vrnemo se iz klica izpis(2) • vrnili smo se iz klica izpis(2) • izpišemo 3 • vrnemo se iz klica izpis(3) • vrnili smo se iz klica izpis(3) • končamo
Izpis nazaj • defizpisNazaj(n): • if n == 1: • print(1) • return • print(n) • izpisNazaj(n - 1)
Ven z 'a'-ji • Iz niza sestavi nov niz (ali lahko spremenimo obstoječega?), ki pa ne vsebuje 'a' jev • defodstraniA(niz): • novi = "" • for znak in niz: • if znak != "a": • novi += znak • return novi
Rekurzivno defodstraniA(niz): if niz == "": return "" prvi = niz[0] preostanek = niz[1:] novi = odstraniA(preostanek) if prvi != "a": return prvi + novi return novi
Fibonacci-jevo zaporedje • a0 = 1 • a1 = 1 • an = an-1 + an-2 • Brez rekurzije def a(n): if n == 0 or n == 1: return 1 sez = [1, 1] for i in range(2, n + 1): sez.append(sez[-2] + sez[-1]) returnsez[-1]
Fibonacci - nerekurzivno • Verjetno lepše pa je takole def a(n): prvi = 1 drugi = 1 for i in range(n): prvi, drugi = drugi, prvi + drugi return prvi
Fibonacci - rekurzija deffib(n): if n == 0 or n == 1: return 1 returnfib(n-1) + fib(n-2)
Seznam besed v nizu • 'Matija Mataja hruške prodaja' • ['Matija', 'Mataja', 'hruške', 'prodaja'] • >>> niz = 'Matija Mataja hruške prodaja' • >>> sez = niz.split(' ') • >>> sez • ['Matija', 'Mataja', 'hruške', 'prodaja'] • >>> niz = 'Matija Mataja hruške prodaja' • >>> sez = niz.split(' ') • >>> sez • ['Matija', '', '', 'Mataja', '', '', '', '', '', '', 'hruške', 'prodaja'] • >>>
Malo čaranja • defseznamBesed(niz): • return [i for i in niz.split(" ") if i != ""] • Seznamski izrazi • [izraz seznam pogoj] • Seveda znamo tudi brez čaranja • Recimo kar • defseznamBesed(niz): • returnniz.split()
Kaj pa z rekurzijo? • Brez split seveda! • Postopek • Določi prvo besedo bes, • na preostanku niza niz rekurzivno izračunaj seznam besed sez, • prvo besedo dodaj na začetek seznama sez in vrni tako popravljen seznam sez.
Zaustavitveni pogoj • Več jih je! • Ko v obdelavo dobimo • niz z eno besedo • [beseda] • niz sestavljen iz samih presledkov • [] • prazen niz • [] • Kako prepoznamo primere: • preostanek je prazen niz • poskušamo pridobiti prvo besedo, a neuspešno • == ''
Koda defseznamBesed(niz): if niz == "": return [] bes, preostanek = razdeliNaPrviBesedi(niz) if bes == "": return [] if preostanek == "": return [bes] sez = seznamBesed(preostanek) sez.insert(0, bes) returnsez
razdeliNaPrviBesedi • Vračamo dva podatka! • Če niza "ni", vrnemo dva prazna niza (besedo in preostanek) • Če je prvi znak presledek • Rezultat je tak, kot bi uporabili to funkcijo na nizu brez prvega (rekurzivni klic) • Če pa prvi ni presledek • Poiščemo mesto, kje nastopa prvič • Find • Če vrne < 0, presledka ni • Če pa je, le razrežemo niz
Koda defrazdeliNaPrviBesedi(niz): if niz == "": return "", "" if niz[0] == " ": returnrazdeliNaPrviBesedi(niz[1:]) ind = niz.find(" ") ifind < 0: return niz, "" return niz[:ind], niz[ind + 1:]