Download presentation
Presentation is loading. Please wait.
Published byMavis Parsons Modified over 8 years ago
1
Recursion ● Recursion or Iteration ● A Common Recursive Design Pattern ● Computing factorials ● Searching a filesystem tree ● Faster exponentiation ● Slow computation of fibonacci numbers
2
Recursion or Iteration Iteration means doing the same action a number of times until some condition is met, e.g. reading a number of records from a file all the records are processed. Recursion means a function calling itself on successively smaller versions of a problem until the problem is small enough that it can be solved directly. Recursion can make heavy use of the program stack, where automatic variables of parent function calls are stored and return addresses for when a child call exits.
3
A common recursive design pattern solution recursive_func( problem ){ if (problem is trivial) return the known solution else return some expression involving call/s to recursive_func(to solve smaller problem/s) }
4
Computing factorials 1 We can define factorial(N) iteratively as 1 x 2 x 3... x N, where... means keep doing the multiplication for all integers between 4 and N-1. Alternatively we can define factorial(N) recursively. IF N == 1: Factorial(N) is 1 IF N > 1: Factorial(N) is Factorial(N-1) x N
5
Computing factorials 2 int factorial(int n){ if(n==1) /* trivial case, return result */ return 1; /* we don't need an else here due to the return after the if clause */ return factorial(n-1)*n; /* reduce the problem to a smaller one */ }
6
Searching a file system tree Data structrures known as trees lend themselves to recursive processing, because a subtree has the same properties as the parent tree, but is smaller than the parent tree. You are already familiar with the use of a filesystem tree to store folders and files as a Windows drive, e.g C: or a Unix mount point e.g. /. Searching such a tree, e.g. for a file with a particular name, involves comparing all of the local names and calling the same function on each of the subtrees.
7
Faster Exponentiation 1 Cryptographic protocols are used to secure messages and create digital signatures of documents. These exponentiate and get remainders using very large prime numbers, e.g. with 1024 binary digits, equivalent to about 300 decimal digits. Let's generate 3 such numbers, A, B and C. When we write A B mod C this means we multiply A to the power of B and get the remainder on dividing by C. In practice we can't multiply A B in one single operation or even directly, because A and B are too large, and to avoid this result using up more memory than we have, we can repeatedly get the remainder (mod C) to make intermediate results smaller, which avoids the numbers being multiplied becoming too large. This works because: IF D = E.F, THEN D mod G = ((E mod G).(F mod G)) mod G E.G. making E=23, F=37 and G=19, 23 % 19 = 4, 37 % 19 = 18, 23 x 37 = 851,851 % 19 = (4 x 18) % 19 = 15
8
Faster Exponentiation 2 We can't even multiply A by itself B times because B is too large. But we can divide B by 2 using integer division Log 2 B times, and using to the order of this smaller number of operations we can obtain A B mod C. Ignoring the remaindering requirement, and to learn how to exponentiate A B using OLog 2 B operations, we are going to write a program to raise a floating point value for A to the power of integer B using the following simplifications: IF B is even, A B is equal to A (B/2) x A (B/2). ELSE, B is odd, A B is equal to A (B/2) x A (B/2) x A. When obtaining B/2, we are using integer division.
9
Faster Exponentiation 3 For example if the number were 2 and the power were 37 and we use sq() to represent the square function, this functionality could be expressed as follows: 2 37 = 2 * sq(2 18 ) 2 18 = sq(2 9 ) 2 9 = 2 * sq(2 4 ) 2 4 = sq(2 2 ) 2 2 = sq(2) therefore: 2 37 = 2 * sq(sq(2*sq(sq(sq(2))))). 2 37 = 137438953472.
10
Faster Exponentiation 4 Using this recursive method of calculating 2 37 involves 7 multiplications instead of 36. Calculating 1.00000001 10000000 recursively involves 35 instead of the 9,999,999 multiplications which would be required in calculating this value iteratively. Repeatedly taking a remainder makes it possible to exponentiate randomly generated prime integers of cryptographic sizes.
11
Recursive Exponentiation Program 1
12
Recursive Exponentiation Program 2
13
Recursive Exponentiation Program 3 Function power is called once from function main. Function power calls itself repeatedly until n == 1 when the function will return a value from each of the calls to the preceding call. Note that the context of each function call, i.e. local variable values for a particular level are preserved until the program returns from that level. The output from program fastmult.c is shown below: Enter a number and a (positive int) power to raise it to 1.00001 1000000 The result is 2.68677343000936241e+43
14
Recursive Exponentiation Program 4 The recursive function calls result in there being a number of instances of the automatic variable a and parameter variables x and n preserved on the program stack when recursion is at its deepest level. This will tend to defeat the use of a debugger with break points and watch variables. Which instance of a watched variable is being seen ? To help with debugging, it is possible to use the standard input facilities of the programming language to pause the program to simulate a breakpoint, and the standard output facilities to add extra output to view automatic variables and parameters. An instrumented version of power() is on the next slide. The instrumented version uses a global int variable level initialised to 0.
15
Recursive Exponentiation Program 5
16
Slow computation of fibonacci numbers 1 Recursive algorithms are not always faster than the iterative equivalent.One example of a slower recursive algorithm involves computing fibonacci numbers. This will only be slower if using an old or small compiler that don't know how to optimise it. if n= 1 or n=2, fibonacci(n) = 1. if n > 2, fibonnaci(n) = fibonacci(n-1) + fibonacci(n-2). The fibonacci series is 1,1,2,3,5,8,13,21,34,55 etc, with each number in the series after the first 2 being the sum of the previous 2.
17
Slow computation of fibonacci numbers 2
18
Tutorial Exercises To compute fib(n) where n is > 8 how many times does fib have to be called to compute fib(n-1), fib(n-2) fib(n-3), fib(n-4), fib(n-5) and fib(n-6). Write and test a function ncfib(x) which returns the number of times fib() has to be called in order to compute fib(x) ? Write and test an iterative function ifib(x) which computes fibonacci(x) iteratively. How many operations does it need and why is it faster ?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.