Recursion - PowerPoint PPT Presentation

About This Presentation
Title:

Recursion

Description:

n General Form of Recursive methods. n Examples of Simple Recursion. n Hand Simulating Recursive methods. n Proving Recursive methods Correct ... – PowerPoint PPT presentation

Number of Views:63
Avg rating:3.0/5.0
Slides: 28
Provided by: csC76
Learn more at: http://www.cs.cmu.edu
Category:
Tags: recursion

less

Transcript and Presenter's Notes

Title: Recursion


1
Recursion
  • n General Form of Recursive methods
  • n Examples of Simple Recursion
  • n Hand Simulating Recursive methods
  • n Proving Recursive methods Correct
  • n Modeling Recursion via Onions
  • n Recursive methods on Naturals/Integers

2
Recursion
  • Recursion is a programming technique in which a
    call to a method appears in that methods body
    (i.e., a method calls itself this is called
    direct recursion)
  • Once you understand recursive methods, they are
    often simpler to write than their iterative
    equivalents
  • In modern programming languages, recursive
    methods may run a bit slower (maybe 5) than
    equivalent iterative methods in a typical
    application, this time is insignificant (most of
    the time will be taken up elsewhere anyway)
  • We will begin by studying the form of general
    recursive methods then apply this form to
    methods operating on int values and finally
    apply that form to methods operating on linked
    lists (where they are most useful). In both cases
    we will discuss how values of these types are
    recursively defined.

3
Fund Raising Iteration vs. Recursion
  • Problem Collect 1,000.00 for charity
  • Assumption Everyone is willing to donate a penny
  • Iterative Solution
  • Visit 100,000 people, asking each for a penny
  • Recursive Solution
  • If you are asked to collect a penny, give a penny
    to the person who asked you for it
  • Otherwise
  • Visit 10 people and ask them to each raise 1/10th
    of the amount of money that you have been asked
    to raise
  • Collect the money that they give you and combine
    it into one bag
  • Give it to the person who asked you to collect
    the money

4
General Form of Recursive methods
  • Solve(Problem)
  • if (Problem is minimal/not decomposable a base
    case)
  • solve Problem directly i.e., without
    recursion
  • else
  • (1) Decompose Problem into one or more
    similar, strictly smaller subproblems
    SP1, SP2, ... , SPN
  • (2) Recursively call Solve (this method) on
    each subproblem Solve(SP1),
    Solve(SP2),..., Solve(SPN)
  • (3) Combine the solutions to these
    subproblems into a solution that solves
    the original Problem

5
factorial In Mathematics and Java
Example using Definition 4! 4 3! 4 3
2! 4 3 2 1! 4 3 2 1 0!
4 3 2 1 1
  • 1 if N 0
  • N!
  • N(N-1)! if N 0
  • int factorial (int n)
  • if (n 0) //Non-decomposable
  • return 1
  • else
  • int subN n-1 //Decompose
  • int subFact factorial(subN) //Solve
    Subproblem
  • return n subFact //Combine

6
Simplified and Iterative factorial
  • int factorial (int n)
  • if (n 0)
  • return 1
  • else
  • return n factorial(n-1)
  • int factorial (int n)
  • int answer 1
  • for (int i1 i
  • answer i
  • return answer

Here we combine the three steps in the previous
else block into a single return statement (one
expression including the decompose, solve, and
combine steps). Compare this method to the one
below it, which operates by iteration. The
iterative version requires the declaration of two
variables and the use of state change operators
(which are always difficult to reason about)
7
pow Raising a Number to a Power
  • 1 if N 0
  • AN
  • AAN-1 if N 0
  • double pow(double a, int n)
  • if (n 0)
  • return 1.
  • else
  • return apow(a,n-1)

Example using Definition A4 A A3 A A
A2 A A A A1 A A A A A0
A A A A 1
Calling pow(a,n)requires exactly n multiplications
The pow in the Java Math library actually
computes its answer using logarithms and
exponentials
8
Simulation of Recursive Methods
  • Assume that a method is computed according to its
    definition by a person in an apartment complex
  • That person can be called to compute an answer
    once he/she computes the answer (possibly helped
    by calling another person in the apartment
    complex), he/she places a return call, and
    reports back the answer to the person who called
    him/her
  • Assume that each person knows the phone number of
    the person living in the apartment underneath
    them, who also has the same set of instructions
    so any person can call the one underneath to
    solve a simpler problem
  • The first method call initiates a sequence of
    calls to people living in lower level apartments
    (each person solving a simpler problem), whose
    answers percolate back to the top, finally
    solving the original problem

9
Hand Simulation of Factorial
n return
n return
n return
n return
...
n return
10
Proof Rules for Recursive Methods
  • To prove that a recursive method, Solve, is
    correct
  • Prove that Solve computes (without recursion) the
    correct answer to any minimal (base case) Problem
  • Base cases are simple, so this should be easy
  • Prove that the argument to any recursive call of
    Solve, e.g. SPI, is strictly smaller (closer to
    the minimal case) than Problem
  • The notion of strictly smaller should be easy to
    understand for the recursive argument, so this
    should be easy
  • Prove that these answers are combined to compute
    the correct answer for Problem
  • In this proof, you may assume that each recursive
    call, Solve(SPI), correctly computes its answer
  • The assumption makes this proof easy
  • Recursion is computable induction (a math concept)

11
Applying the Proof Rules
  • factorial (recurring on the parameter n)
  • factorial correctly returns 1 for the minimal
    argument 0.
  • In factorial(n-1), n-1 is always closer to 0 than
    n is.
  • Assume factorial(n-1) computes the correct
    answer.
  • n times this value is, by definition, the correct
    value of factorial(n)
  • pow (recurring on the parameter n)
  • pow correctly returns 1 for the minimal argument
    0.
  • In pow(a,n-1), n-1 is always closer to 0 than n
    is.
  • Assume pow(a,n-1) computes the correct answer,
    an-1.
  • apow(a,n-1) is aan-1 is an, the correct value
    of pow(a,n)

12
Proof Rules and Bad Factorials
  • int factorial (int n)
  • if (n 0)
  • return 0 //0! is not 0
  • else
  • return nfactorial(n-1)
  • int factorial (int n)
  • if (n 0)
  • return 1
  • else
  • return factorial(n1)/(n1) //n1 not closer
    to 0
  • int factorial (int n)
  • if (n 0)

13
Proof Rules and Bad Factorials (cont)
  • In the first method, the wrong answer (0) is
    returned for the base case since everything
    depends on the base case, ultimately this method
    always returns 0
  • In the second method, n1 is farther away from
    the base case this method will continue calling
    factorial with ever larger arguments, until the
    maximum int value is exceeded a runaway (or
    infinite) recursion (actually, each recursive
    call can take up some space, so eventually memory
    is exhausted).
  • In the third method, the wrong answer is returned
    by incorrectly combining n and the solved
    subproblem this method returns one more than the
    sum of all the integers from 1 to n (an
    interesting method in its own right) not the
    product of these values
  • In the first method, it always returns the wrong
    answer the second method never returns an
    answer, the third method returns the correct
    answer only in the base case

14
fpow a faster version of pow
Note if N is odd N/2 truncates so 7/2 3
  • 1 if N 0
  • AN B2 where B AN/2 if N 0 and N is Even
  • AB2 where B AN/2 if N 0 and N is Odd
  • int fpow(double a, int n)
  • if (n 0)
  • return 1.
  • else
  • double b fpow(a,n/2)
  • if (n2 0)
  • return bb
  • else
  • return abb

Calling fpow(a,n)requires between at least log2n
and at most 2log2n multiplications Compare this
complexity to calling pow(a,n)requiring n
multiplications Contemporary cryptography raises
large numbers to huge (hundred digit) powers it
needs a fast method
15
Recursive Definition of Naturals
  • 0 is the smallest Natural
  • It is minimal, and cannot be decomposed
  • z(x) is true if x is zero and false if x is
    non-zero
  • The successor of a Natural is a Natural
  • If x is a Natural, s(x) is a Natural
  • The successor of x is x1
  • If x is a non-0 Natural, p(x) is a Natural
  • The predecessor of x is x-1
  • p(0) throws an exception
  • Note
  • z(s(x)) is always false
  • p(s(x)) x
  • s(p(x)) x only if X ? 0

16
Onion Model of Recursive Naturals
Every Onion is either Base Case The
core Recursive Case A layer of skin around a
smaller onion (which may be the core, or some
deeper layer) The value of an onion is the
number of layers of skin beyond the core
17
Computation with Naturals
  • Lets Define 3 methods that operate on Naturals
    in Java
  • int s(int x) return x1
  • int p(int x)
  • if (x0)
  • throw new IllegalArgumentException("p with
    x0")
  • return x-1
  • bool z(int x) return x 0
  • We can define all common operators (both
    arithmetic and relational) on Naturals by writing
    simple recursive methods that use these three
    methods

18
Recursive methods on Naturals
  • int sum(int a, int b)
  • if (z(a))
  • return b
  • else
  • return s(sum(p(a),b)) //1 (a-1 b)
  • int sum(int a, int b)
  • if (z(a))
  • return b
  • else
  • return sum(p(a), s(b)) //(a-1) (b1)
  • In both sum methods, a gets closer to 0 in
    recursive calls

19
Recursive methods on Naturals II
  • int product(int a, int b)
  • if (z(a))
  • return 0
  • else
  • return sum(b,product(p(a),b)) //b (a-1)b
  • int power(int a, int b)
  • if (z(b))
  • return 1
  • else
  • return product(a, power(a,p(b)))//a ab-1

20
Recursive methods on Naturals III
  • bool equal(int a, int b) //Is a b
  • if (z(a) z(b)) //If either is 0...
  • return z(a) z(b) //return whether both
    are 0
  • else
  • return equal(p(a), p(b)) //Is (a-1) (b-1)
  • bool less(int a, int b) //Is a
  • if (z(b)) //Nothing is
  • return false
  • else if (z(a)) //If b!0, a0, then a
  • return true
  • else
  • return less(p(s),p(b)) //Is (a-1)

21
Recursive methods on Naturals IV
  • bool even(int a)
  • if (z(a)) //True if 0
  • return true
  • else //Opposite of even(a-1)
  • return !even(p(a))
  • bool odd(int a)
  • if (z(a)) //False if 0
  • return false
  • else //Opposite of odd(a-1)
  • return !odd(p(a))

22
Printing an Integers Digits
  • void print (int i)
  • if (i 10)
  • System.out.print(i) // print(i/10)
  • else //System.out.print(i10)
  • print(i/10)
  • System.out.println(i10)
  • print correctly prints all 1-digit values 0 - 9.
  • In print(i/10), i/10 is one digit closer to 0 - 9
    than i is.
  • Assume print (i/10) correctly prints all the
    digits in i/10 in the correct order
  • Printing i/10 (all digits but the last) and then
    printing i10 (the last digit), prints all the
    digits in i in order

The code above is simplified by bottom factoring
and test reversal and noting for i
23
Printing an Integers Digits in Reverse
  • void printReversed (int i)
  • if (i
  • System.out.print(i) //if (i 10)
  • else // System.out.print(i/10)
  • System.out.print(i10)
  • printReversed(i/10)
  • printReversed correctly prints all 1-digit
    values 0 - 9.
  • In printReversed(i/10), i/10 is closer to 0-9
    than i is.
  • Assume printReversed(i/10) correctly prints all
    the digits in i/10 reversed.
  • Printing the last digit, i10, and then printing
    the i/10 reversed prints all the digits in i
    reversed.

24
Converting an int to a string
  • String toString (int i)
  • if (i
  • return ""(char)(i0)
  • else
  • return toString(i/10) (char)(i100)
  • toString correctly returns all 1-digit values 0
    - 9.
  • In toString(i/10), i/10 is one digit closer to
    0-9 than i is.
  • Assume toString(i/10) correctly returns a String
    of all the digits in I/10.
  • Then, after appending the char equivalent of i10
    at the end of this String correctly stores the
    String equivalent of i.

25
Synthesizing Recursive Methods
  • Find the base (non-decomposable) case(s)
  • Write the code that detects the base case(s) and
    returns the correct answer for them without using
    recursion
  • Assume that you can decompose all non
    base-case(s) and then solve these smaller
    subproblems via recursion
  • Choose the decomposition
  • There should be some natural decomposition
  • Write code that combines these solved subproblems
    (often there is just one) to solve the original
    problem
  • Typical decompositions
  • Integers i - something or i/something
    (digit at a time)
  • Linked Lists l.next

26
Problems
  • Write the following method public static
    String reverse (String s) recursively. Choose an
    appropriate base case, recursive call (hint
    substring method using one parameter), and a way
    to combine (hint ) solved smaller problems to
    solve the original problem. reverse("abcd")
    should return "dcba"
  • Write the following method public static int
    toInt (String s) recursively. It is like
    parseInt, but only for non-negative
    valuestoInt("138") should return 138

27
Problems (continued)
  • Write the following method public static
    boolean equals (String s1, String s2)
    recursively. Its recursive structure is like that
    of the equals methods for ints.
  • Write the following method public static int
    compare (String s1, String s2) recursively.
    Its recursive structure is similar to equals,
    above.
Write a Comment
User Comments (0)
About PowerShow.com