{"id":50,"date":"2019-02-27T08:54:30","date_gmt":"2019-02-27T08:54:30","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/?post_type=chapter&#038;p=50"},"modified":"2019-03-20T17:21:05","modified_gmt":"2019-03-20T17:21:05","slug":"ulevaade","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/chapter\/ulevaade\/","title":{"raw":"Rekursiooni sissejuhatus","rendered":"Rekursiooni sissejuhatus"},"content":{"raw":"<h1 class=\"vspace\">Funktsioonist kordavalt<\/h1>\r\n<p class=\"vspace\">Oleme kasutanud erinevaid funktsioone - osa neist on olnud Pythonis valmis v\u00f5i oleme need importinud m\u00f5nest moodulist, teised oleme ise defineerinud. Meeldetuletuseks on <a href=\"https:\/\/web.htk.tlu.ee\/digitaru\/programmeerimine\/chapter\/alamprogramm-funktsioon\/\">programmeerimise \u00f5piku 6. peat\u00fckk<\/a> funktsioonidele p\u00fchendatud.<\/p>\r\n<p class=\"vspace\">Meenutame, et funktsioon tagastab v\u00e4\u00e4rtuse, mis m\u00e4\u00e4ratakse v\u00f5tmes\u00f5na <code>return<\/code> abil. Kui seda ei tehta, siis tagastatakse spetsiaalne v\u00e4\u00e4rtus <code>None<\/code> (eesti keeles \"mitte miski\"). Ilma tagastusv\u00e4\u00e4rtuseta funktsioonide roll on lihtsalt midagi \u00e4ra teha, nt <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print<\/code> v\u00e4ljastab oma argumendi(d) ekraanile, kuid ei tagasta midagi.<\/p>\r\n<p class=\"vspace\">Olgu meil j\u00e4rgmine programm:<\/p>\r\n\r\n<div>\r\n<div class=\"syntaxhighlighter nogutter  python\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def summa(a, b):\r\n    return a + b\r\n\r\ndef topelt_summa(a, b):\r\n    return 2 * summa(a, b)\r\n\r\nprint(summa(3, 4))<\/pre>\r\n<\/div>\r\n<\/div>\r\n<p class=\"vspace\">N\u00e4eme, et funktsioon <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">summa<\/code><\/code> on kutsutud v\u00e4lja funktsiooni <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">topelt_summa<\/code> definitsioonis ja ka p\u00f5hiprogrammis (funktsiooni <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print<\/code><\/code> argumendina). Veel saab funktsiooni v\u00e4lja kutsuda Thonny k\u00e4sureaaknas (<em>Shell<\/em>):<\/p>\r\n\r\n<div class=\"vspace\"><\/div>\r\n<div>\r\n<div class=\"syntaxhighlighter nogutter  python\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">&gt;&gt;&gt; summa(5, 7)\r\n12<\/pre>\r\n<\/div>\r\n<\/div>\r\n<h1 class=\"vspace\">Rekursiivne v\u00e4ljakutse<\/h1>\r\n<p class=\"vspace\">Eespool kutsuti \u00fcks funktsioon v\u00e4lja teise funktsiooni definitsioonis. Tegelikult saab funktsiooni v\u00e4lja kutsuda tema enda definitsioonis. Sellisel juhul on tegemist <em>rekursiivse v\u00e4ljakutsega<\/em>. Rekursioon on funktsioonide defineerimise viis, kus defineeritav funktsioon kutsub v\u00e4lja iseennast (kuid erineva argumendi v\u00e4\u00e4rtusega).<\/p>\r\n<p class=\"vspace\">Rekursioon sobib h\u00e4sti selliste \u00fclesannete lahendamiseks, kus tervik\u00fclesannet saab jaotada \"v\u00e4iksemateks\" samasugusteks \u00fclesanneteks. Oluline on, et l\u00f5puks oleks need \"v\u00e4iksemad\" \u00fclesanded nii v\u00e4ikesed, et nende lahendamine oleks v\u00e4ga lihtne.<\/p>\r\n<p class=\"vspace\">\u00dcks tuntumaid rekursiooni n\u00e4iteid on <a class=\"urllink\" href=\"https:\/\/et.wikipedia.org\/wiki\/Faktoriaal\" target=\"_blank\" rel=\"noopener\">faktoriaali<\/a> arvutamine. Positiivse t\u00e4isarvu <em>n<\/em> faktoriaal (t\u00e4histus <em>n!<\/em>) on <em>n<\/em> esimese positiivse t\u00e4isarvu korrutis. N\u00e4iteks <em>4! = 1 \u00b7 2 \u00b7 3 \u00b7 4 = 24<\/em>. Eraldi on kokku lepitud, et <em>0! = 1<\/em>, samuti <em>1! = 1<\/em>. Rekursiivsena saab faktoriaali leidmist kirjeldada nii, et iga j\u00e4rgmise arvu faktoriaali saame esitada eelmise arvu faktoriaali abil. N\u00e4iteks <em>4! = 4 \u00b7 3!<\/em> ja omakorda <em>3! = 3 \u00b7 2!<\/em> ning <em>2! = 2 \u00b7 1!<\/em>. L\u00f5puks <em>1! = 1<\/em> v\u00f5i kui tahame ka <em>0<\/em> m\u00e4ngu v\u00f5tta, siis v\u00f5ime \u00f6elda ka, et <em>1! = 1 \u00b7 0!<\/em> ja <em>0! = 1<\/em>. \u00dcldistatult saame kaks olukorda:<\/p>\r\n\r\n<ul>\r\n \t<li><em>n! = 1<\/em>, kui <em>n = 0<\/em><\/li>\r\n \t<li><em>n! = n \u00b7 (n-1)!<\/em>, kui <em>n &gt; 0<\/em><\/li>\r\n<\/ul>\r\n<p class=\"vspace\">Programselt saame selle funktsiooni kirja panna j\u00e4rgnevalt:<\/p>\r\n\r\n<div>\r\n<div class=\"syntaxhighlighter nogutter  python\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def faktoriaal(n):\r\n    if n == 0:             # Rekursiooni baas\r\n        return 1\r\n    else:                  # Rekursiooni samm\r\n        return n * faktoriaal(n-1)\r\n\r\nprint(faktoriaal(4))\r\nprint(faktoriaal(0))\r\nprint(faktoriaal(400))<\/pre>\r\n<\/div>\r\n<\/div>\r\n<p class=\"vspace\">Korrektses rekursiivses funktsioonis on alati mitu haru. Protsessi l\u00f5ppemiseks peab v\u00e4hemalt \u00fcks haru olema ilma rekursiivse v\u00e4ljakutseta. Seda haru nimetatakse <em>rekursiooni baasiks<\/em>. Rekursiivse v\u00e4ljakutsega haru nimetatakse <em>rekursiooni sammuks<\/em>. Rekursiivsete v\u00e4ljakutsetega v\u00f5ib olla ka mitu haru. Samuti v\u00f5ib harva olla kasulik m\u00e4\u00e4rata mitu erinevat rekursiooni baasi.<\/p>\r\n\r\n<h1 class=\"vspace\">M\u00f5ned n\u00e4ited<\/h1>\r\n<p class=\"vspace\">Sarnaselt ts\u00fcklile v\u00f5imaldab rekursioon kirjeldada korduvt\u00e4idetavaid protsesse.<\/p>\r\n<p class=\"vspace\">M\u00e4nguliselt saab rekursiooni ja ka teisi programmeerimise kontruktsioone harjutada m\u00e4ngus <a class=\"urllink\" href=\"http:\/\/lightbot.com\/flash.html\" target=\"_blank\" rel=\"noopener\">Lightbot<\/a>. Tasemetel 3.1 ja 3.2 saabki hakkama ainult nii, et protseduur iseennast v\u00e4lja kutsub.<\/p>\r\n<p class=\"vspace\">Proovi, mida teeb j\u00e4rgmine programm.<\/p>\r\n\r\n<div>\r\n<div class=\"syntaxhighlighter nogutter  python\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def rek_fun(n):\r\n    if n &gt; 0:\r\n        print(\"P\u00f5hi!\")\r\n    else:\r\n        print(n)\r\n        rek_fun(n + 2)\r\n\r\nrek_fun(-7)<\/pre>\r\n<\/div>\r\n<\/div>\r\n<p class=\"vspace\">Proovi programmi muuta ja k\u00e4ivita uuesti. N\u00e4iteks v\u00f5ib <code>n &gt; 0<\/code> asendada m\u00f5ne muu tingimusega v\u00f5i muuta ridade <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print(n)<\/code><\/code> ja <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">rek_fun(n + 2)<\/code><\/code> j\u00e4rjekorda.<\/p>\r\n<p class=\"vspace\">Rekursiivne funktsioon on tegelikult tavaline Pythoni funktsioon. Seega v\u00f5ib tal olla ka mitu argumenti.<\/p>\r\n\r\n<h3 class=\"vspace\">Enesekontroll (1 \u00fclesanne)<\/h3>\r\n<div>\r\n\r\n<code>[h5p id=\"24\"]<\/code>\r\n\r\n<\/div>\r\n<p class=\"vspace\">Rekursiooni kasutatakse laialdaselt programmeerimises, arvutiteaduses ja matemaatikas, samuti keeleteaduses, muusikas, kunstis jne.<\/p>\r\n<p class=\"vspace\">Kunstis v\u00f5ib v\u00e4lja tuua n\u00e4iteks <a class=\"urllink\" href=\"http:\/\/www.mcescher.com\/\" target=\"_blank\" rel=\"noopener\">Maurits Cornelis Escheri<\/a> (1898-1972) t\u00f6\u00f6d.<\/p>","rendered":"<h1 class=\"vspace\">Funktsioonist kordavalt<\/h1>\n<p class=\"vspace\">Oleme kasutanud erinevaid funktsioone &#8211; osa neist on olnud Pythonis valmis v\u00f5i oleme need importinud m\u00f5nest moodulist, teised oleme ise defineerinud. Meeldetuletuseks on <a href=\"https:\/\/web.htk.tlu.ee\/digitaru\/programmeerimine\/chapter\/alamprogramm-funktsioon\/\">programmeerimise \u00f5piku 6. peat\u00fckk<\/a> funktsioonidele p\u00fchendatud.<\/p>\n<p class=\"vspace\">Meenutame, et funktsioon tagastab v\u00e4\u00e4rtuse, mis m\u00e4\u00e4ratakse v\u00f5tmes\u00f5na <code>return<\/code> abil. Kui seda ei tehta, siis tagastatakse spetsiaalne v\u00e4\u00e4rtus <code>None<\/code> (eesti keeles &#8220;mitte miski&#8221;). Ilma tagastusv\u00e4\u00e4rtuseta funktsioonide roll on lihtsalt midagi \u00e4ra teha, nt <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print<\/code> v\u00e4ljastab oma argumendi(d) ekraanile, kuid ei tagasta midagi.<\/p>\n<p class=\"vspace\">Olgu meil j\u00e4rgmine programm:<\/p>\n<div>\n<div class=\"syntaxhighlighter nogutter  python\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def summa(a, b):\r\n    return a + b\r\n\r\ndef topelt_summa(a, b):\r\n    return 2 * summa(a, b)\r\n\r\nprint(summa(3, 4))<\/pre>\n<\/div>\n<\/div>\n<p class=\"vspace\">N\u00e4eme, et funktsioon <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">summa<\/code><\/code> on kutsutud v\u00e4lja funktsiooni <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">topelt_summa<\/code> definitsioonis ja ka p\u00f5hiprogrammis (funktsiooni <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print<\/code><\/code> argumendina). Veel saab funktsiooni v\u00e4lja kutsuda Thonny k\u00e4sureaaknas (<em>Shell<\/em>):<\/p>\n<div class=\"vspace\"><\/div>\n<div>\n<div class=\"syntaxhighlighter nogutter  python\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">&gt;&gt;&gt; summa(5, 7)\r\n12<\/pre>\n<\/div>\n<\/div>\n<h1 class=\"vspace\">Rekursiivne v\u00e4ljakutse<\/h1>\n<p class=\"vspace\">Eespool kutsuti \u00fcks funktsioon v\u00e4lja teise funktsiooni definitsioonis. Tegelikult saab funktsiooni v\u00e4lja kutsuda tema enda definitsioonis. Sellisel juhul on tegemist <em>rekursiivse v\u00e4ljakutsega<\/em>. Rekursioon on funktsioonide defineerimise viis, kus defineeritav funktsioon kutsub v\u00e4lja iseennast (kuid erineva argumendi v\u00e4\u00e4rtusega).<\/p>\n<p class=\"vspace\">Rekursioon sobib h\u00e4sti selliste \u00fclesannete lahendamiseks, kus tervik\u00fclesannet saab jaotada &#8220;v\u00e4iksemateks&#8221; samasugusteks \u00fclesanneteks. Oluline on, et l\u00f5puks oleks need &#8220;v\u00e4iksemad&#8221; \u00fclesanded nii v\u00e4ikesed, et nende lahendamine oleks v\u00e4ga lihtne.<\/p>\n<p class=\"vspace\">\u00dcks tuntumaid rekursiooni n\u00e4iteid on <a class=\"urllink\" href=\"https:\/\/et.wikipedia.org\/wiki\/Faktoriaal\" target=\"_blank\" rel=\"noopener\">faktoriaali<\/a> arvutamine. Positiivse t\u00e4isarvu <em>n<\/em> faktoriaal (t\u00e4histus <em>n!<\/em>) on <em>n<\/em> esimese positiivse t\u00e4isarvu korrutis. N\u00e4iteks <em>4! = 1 \u00b7 2 \u00b7 3 \u00b7 4 = 24<\/em>. Eraldi on kokku lepitud, et <em>0! = 1<\/em>, samuti <em>1! = 1<\/em>. Rekursiivsena saab faktoriaali leidmist kirjeldada nii, et iga j\u00e4rgmise arvu faktoriaali saame esitada eelmise arvu faktoriaali abil. N\u00e4iteks <em>4! = 4 \u00b7 3!<\/em> ja omakorda <em>3! = 3 \u00b7 2!<\/em> ning <em>2! = 2 \u00b7 1!<\/em>. L\u00f5puks <em>1! = 1<\/em> v\u00f5i kui tahame ka <em>0<\/em> m\u00e4ngu v\u00f5tta, siis v\u00f5ime \u00f6elda ka, et <em>1! = 1 \u00b7 0!<\/em> ja <em>0! = 1<\/em>. \u00dcldistatult saame kaks olukorda:<\/p>\n<ul>\n<li><em>n! = 1<\/em>, kui <em>n = 0<\/em><\/li>\n<li><em>n! = n \u00b7 (n-1)!<\/em>, kui <em>n &gt; 0<\/em><\/li>\n<\/ul>\n<p class=\"vspace\">Programselt saame selle funktsiooni kirja panna j\u00e4rgnevalt:<\/p>\n<div>\n<div class=\"syntaxhighlighter nogutter  python\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def faktoriaal(n):\r\n    if n == 0:             # Rekursiooni baas\r\n        return 1\r\n    else:                  # Rekursiooni samm\r\n        return n * faktoriaal(n-1)\r\n\r\nprint(faktoriaal(4))\r\nprint(faktoriaal(0))\r\nprint(faktoriaal(400))<\/pre>\n<\/div>\n<\/div>\n<p class=\"vspace\">Korrektses rekursiivses funktsioonis on alati mitu haru. Protsessi l\u00f5ppemiseks peab v\u00e4hemalt \u00fcks haru olema ilma rekursiivse v\u00e4ljakutseta. Seda haru nimetatakse <em>rekursiooni baasiks<\/em>. Rekursiivse v\u00e4ljakutsega haru nimetatakse <em>rekursiooni sammuks<\/em>. Rekursiivsete v\u00e4ljakutsetega v\u00f5ib olla ka mitu haru. Samuti v\u00f5ib harva olla kasulik m\u00e4\u00e4rata mitu erinevat rekursiooni baasi.<\/p>\n<h1 class=\"vspace\">M\u00f5ned n\u00e4ited<\/h1>\n<p class=\"vspace\">Sarnaselt ts\u00fcklile v\u00f5imaldab rekursioon kirjeldada korduvt\u00e4idetavaid protsesse.<\/p>\n<p class=\"vspace\">M\u00e4nguliselt saab rekursiooni ja ka teisi programmeerimise kontruktsioone harjutada m\u00e4ngus <a class=\"urllink\" href=\"http:\/\/lightbot.com\/flash.html\" target=\"_blank\" rel=\"noopener\">Lightbot<\/a>. Tasemetel 3.1 ja 3.2 saabki hakkama ainult nii, et protseduur iseennast v\u00e4lja kutsub.<\/p>\n<p class=\"vspace\">Proovi, mida teeb j\u00e4rgmine programm.<\/p>\n<div>\n<div class=\"syntaxhighlighter nogutter  python\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">def rek_fun(n):\r\n    if n &gt; 0:\r\n        print(\"P\u00f5hi!\")\r\n    else:\r\n        print(n)\r\n        rek_fun(n + 2)\r\n\r\nrek_fun(-7)<\/pre>\n<\/div>\n<\/div>\n<p class=\"vspace\">Proovi programmi muuta ja k\u00e4ivita uuesti. N\u00e4iteks v\u00f5ib <code>n &gt; 0<\/code> asendada m\u00f5ne muu tingimusega v\u00f5i muuta ridade <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print(n)<\/code><\/code> ja <code><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">rek_fun(n + 2)<\/code><\/code> j\u00e4rjekorda.<\/p>\n<p class=\"vspace\">Rekursiivne funktsioon on tegelikult tavaline Pythoni funktsioon. Seega v\u00f5ib tal olla ka mitu argumenti.<\/p>\n<h3 class=\"vspace\">Enesekontroll (1 \u00fclesanne)<\/h3>\n<div>\n<p><code><\/p>\n<div id=\"h5p-24\">\n<div class=\"h5p-iframe-wrapper\"><iframe id=\"h5p-iframe-24\" class=\"h5p-iframe\" data-content-id=\"24\" style=\"height:1px\" src=\"about:blank\" frameBorder=\"0\" scrolling=\"no\" title=\"rekursioon-1-1-\u00fcksk\u00fcs\"><\/iframe><\/div>\n<\/div>\n<p><\/code><\/p>\n<\/div>\n<p class=\"vspace\">Rekursiooni kasutatakse laialdaselt programmeerimises, arvutiteaduses ja matemaatikas, samuti keeleteaduses, muusikas, kunstis jne.<\/p>\n<p class=\"vspace\">Kunstis v\u00f5ib v\u00e4lja tuua n\u00e4iteks <a class=\"urllink\" href=\"http:\/\/www.mcescher.com\/\" target=\"_blank\" rel=\"noopener\">Maurits Cornelis Escheri<\/a> (1898-1972) t\u00f6\u00f6d.<\/p>\n","protected":false},"author":12,"menu_order":1,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-50","chapter","type-chapter","status-publish","hentry"],"part":45,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapters\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/wp\/v2\/users\/12"}],"version-history":[{"count":3,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapters\/50\/revisions"}],"predecessor-version":[{"id":146,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapters\/50\/revisions\/146"}],"part":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/parts\/45"}],"metadata":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapters\/50\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/pressbooks\/v2\/chapter-type?post=50"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/wp\/v2\/contributor?post=50"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara\/wp-json\/wp\/v2\/license?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}