Chapter 11 · Chapter Goals • To learn to “think recursively” • To be able to use recursive...
Transcript of Chapter 11 · Chapter Goals • To learn to “think recursively” • To be able to use recursive...
RECURSION
11/14/16 1
Chapter 11
Chapter Goals • Tolearnto“thinkrecursively”• Tobeabletouserecursivehelperfunc5ons
• Tounderstandtherela5onshipbetweenrecursionanditera5on• Tounderstandwhentheuseofrecursionaffectstheefficiencyofanalgorithm
• Toanalyzeproblemsthataremucheasiertosolvebyrecursionthanbyitera5on
• Toprocessdatawithrecursivestructuresusingmutualrecursion
11/14/16 Page 2
Contents • TriangleNumbersRevisited
• ProblemSolving:ThinkingRecursively
• RecursiveHelperFunc5ons• TheEfficiencyofRecursion
• Permuta5ons
• Backtracking• MutualRecursion
11/14/16 Page 3
11.1 Triangle Numbers Revisited • Triangleshapeofsidelength4:[]
[][]
[][][] [][][][]
• Willuserecursiontocomputetheareaofatriangleofwidthn,assumingeach[] squarehasanareaof1
• Alsocalledthenthtrianglenumber
• Thethirdtrianglenumberis6,thefourthis10
Page 4 11/14/16
Handling Triangle of Width 1 • Thetriangleconsistsofasinglesquare• Itsareais1• Takecareofthiscasefirst:
11/14/16 Page 5
deftriangleArea(sideLength):ifsideLength==1:return1...
Handling The General Case • Assumeweknowtheareaofthesmaller,coloredtriangle:
[] [][] [][][] [][][][]
• Areaoflargertrianglecanbecalculatedas
11/14/16 Page 6
area=smallerArea+sideLength
smallerSideLength=sideLength-1smallerArea=triangleArea(smallerSideLength)
• Togettheareaofthesmallertriangle
• CallthetriangleArea()func5on:
Computing the Area of a Triangle With Width 4
• triangleArea()func5onmakesasmallertriangleofwidth3
• ItcallstriangleArea()onthattriangle
• Thatfunc5onmakesasmallertriangleofwidth2
• ItcallstriangleArea()onthattriangle
• Thatfunc5onmakesasmallertriangleofwidth1
• ItcallstriangleArea()onthattriangle
• Thatfunc5onreturns1
• Thefunc5onreturnssmallerArea+sideLength =1+2=3
• Thefunc5onreturnssmallerArea+sideLength=3+3=6
• Thefunc5onreturnssmallerArea+sideLength=6+4=10
11/14/16 Page 7
Recursive Computation • Arecursivecomputa.onsolvesaproblembyusingthesolu5ontothesameproblemwithsimplerinputs
• CallpaWernofarecursivefunc.oniscomplicated
• Key:Don’tthinkaboutit
11/14/16 Page 8
Successful Recursion • Everyrecursivecallmustsimplifythecomputa5oninsomeway
• Theremustbespecialcasestohandlethesimplestcomputa5onsdirectly
11/14/16 Page 9
Other Ways to Compute Triangle Numbers
• Theareaofatriangleequalsthesum:
1+2+3+...+sideLength
• Usingasimpleloop:
area=0;foriinrange(1,(sideLength+1),1):area=area+i
• Usingmath:
1+2+...+n=n×(n+1)/2=>n*(n+1)/2
11/14/16 Page 10
Trianglenumbers.py
Page 11 11/14/16
Special Topic 11.1 • AnObject-Orientedversionofthetrianglesprogram
• Generalcase:computetheareaofthelargertriangleassmallerArea+self._sideLength.
• Togetthesmallerarea:
Page 12
classTriangledef__init__(self,sideLength):self._sideLength=sideLengthdefgetArea(self):ifself._sideLength==1:return1...
smallerTriangle=Triangle(self._sideLength-1)smallerArea=smallerTriangle.getArea()area=smallerArea+self._sideLength
11/14/16
Common Error 11.1 • Infiniterecursion:
• Afunc5oncallingitselfoverandoverwithnoendinsight.• Thecomputerneedssomeamountofmemoryforbookkeepingduringeachcall.
• Adersomenumberofcalls,allmemorythatisavailableforthispurposeisexhausted.
• Yourprogramshutsdownandreportsa“stackoverflow”.
• Causes:• Theargumentsdon’tgetsimplerorbecauseaspecialtermina5ngcaseismissing.
Page 13 11/14/16
Thinking Recursively • Problem:Testwhetherasentenceisapalindrome
• Palindrome:Astringthatisequaltoitselfwhenyoureverseallcharacters• Aman,aplan,acanal–Panama!• Gohangasalami,I’malasagnahog• Madam,I’mAdam
11/14/16 Page 14
Implement IsPalindrome() Function
Page 15
##Testswhetherastringisapalindrome.#@paramtextastringthatisbeingchecked#@returnTrueiftextisapalindrome,Falseotherwise#defisPalindrome(text):...
11/14/16
Thinking Recursively: Step 1 • Considervariouswaystosimplifyinputs.
• Severalpossibili5es:
• Removethefirstcharacter
• Removethelastcharacter
• Removeboththefirstandlastcharacters
• Removeacharacterfromthemiddle
• Cutthestringintotwohalves
11/14/16 Page 16
Thinking Recursively: Step 2 (1) • Combinesolu5onswithsimplerinputsintoasolu5onoftheoriginal
problem.
• Mostpromisingsimplifica5on:Removebothfirstandlastcharacters.
• “adam,I’mAda”isapalindrometoo!
• Thus,awordisapalindromeif
• ThefirstandlastleGersmatch,and
• WordobtainedbyremovingthefirstandlastleGersisapalindrome
11/14/16 Page 17
Thinking Recursively: Step 2 (2) • WhatiffirstorlastcharacterisnotaleWer?Ignoreit
• IfthefirstandlastcharactersareleGers,checkwhethertheymatch;ifso,removebothandtestshorterstring
• Iflastcharacterisn’taleGer,removeitandtestshorterstring
• Iffirstcharacterisn’taleGer,removeitandtestshorterstring
Page 18 11/14/16
Thinking Recursively: Step 3 • Findsolu5onstothesimplestinputs.
• Stringswithtwocharacters
• Nospecialcaserequired;steptwosMllapplies
• Stringswithasinglecharacter
• Theyarepalindromes
• Theemptystring
• Itisapalindrome
Page 19 11/14/16
Thinking Recursively: Step 4 (1) • Implementthesolu5onbycombiningthesimplecasesandthe
reduc5onstep.
Page 20
Continued
defisPalindrome(text):length=len(text)#Separatecaseforshorteststrings.iflength<=1:returnTrueelse:#Getfirstandlastcharacters,convertedto#lowercase.first=text[0].lower()last=text[length-1].lower()
11/14/16
Thinking Recursively: Step 4 (2)
Page 21
#Nonbasecaseiffirst.isalpha()andlast.isalpha():#Bothareletters.iffirst==last:#Removebothfirstandlastcharacter.shorter=text[1:length-1]returnisPalindrome(shorter)else:returnFalseelifnotlast.isalpha():#Removelastcharacter.shorter=text[0:length-1]returnisPalindrome(shorter)else:#Removefirstcharacter.shorter=text[1:length]returnisPalindrome(shorter)
11/14/16
Recursive Helper functions • Some5mesitiseasiertofindarecursivesolu5onifyoumakeaslightchangetotheoriginalproblem.
• Considerthepalindrometestofprevioussec5on.
• Itisabitinefficienttoconstructnewstringobjectsineverystep.
11/14/16 Page 22
Substring Palindromes (1) • Ratherthantes5ngwhetherthesentenceisapalindrome,checkwhetherasubstringisapalindrome:
11/14/16 Page 23
##Recursivelytestswhetherasubstringis#apalindrome.#@paramtextastringthatisbeingchecked#@paramstarttheindexofthefirstcharacterofthesubstring#@paramendtheindexofthelastcharacterofthesubstring#@returnTrueifthesubstringisapalindrome#defsubstringIsPalindrome(text,start,end):
Substring Palindromes (2) • Then,simplycallthehelperfunc5onwithposi5onsthattesttheen5restring:
11/14/16 Page 24
defisPalindrome(text):returnsubstringIsPalindrome(text,0,len(text)–1)
Recursive Helper function
11/14/16 Page 25
Continued
defsubstringIsPalindrome(text,start,end):#Separatecaseforsubstringsoflength0and1.ifstart>=end:returnTrueelse:#Getfirstandlastcharacters,convertedtolowercase.first=text[start].lower()last=text[end].lower()
Recursive Helper Function
11/14/16 Page 26
iffirst.isalpha()andlast.isalpha():iffirst==last:#Testsubstringthatdoesn’tcontainthematching#letters.returnsubstringIsPalindrome(text,start+1,end-1)else:returnFalseelifnotlast.isalpha():#Testsubstringthatdoesn’tcontainthelastcharacter.returnsubstringIsPalindrome(text,start,end-1)else:#Testsubstringthatdoesn’tcontainthefirst#character.returnsubstringIsPalindrome(text,start+1,end)