fundamentals of programmingce.sharif.edu/courses/92-93/1/ce153-1/resources... · 1 sharif...
TRANSCRIPT
Fall 2013
Instructor: Reza Entezari-Maleki
Email: [email protected]
Sharif University of Technology 1
Fundamentals of Programming Session 13
These slides have been created using Deitel’s slides
Outlines
Recursion
Example Using Recursion: Fibonacci Series
Recursion vs. Iteration
Tower of Hanoi
2
A recursive function is a function that calls itself either directly or
indirectly through another function.
A recursive function is called to solve a problem.
The function actually knows how to solve only the simplest case(s), or
so-called base case(s).
If the function is called with a base case, the function simply returns a
result.
If the function is called with a more complex problem, the function
divides the problem into two conceptual pieces: a piece that the function
knows how to do and a piece that it does not know how to do.
Because this new problem looks like the original problem, the function
launches (calls) a fresh copy of itself to go to work on the smaller
problem—this is referred to as a recursive call and is also called the
recursion step.3
Recursion
The factorial of a nonnegative integer n, written n! (and
pronounced “n factorial”), is the product n · (n –1) · (n – 2) · … · 1
with 1! equal to 1, and 0! defined to be 1.
The factorial of an integer, number, greater than or equal
to 0 can be calculated iteratively (nonrecursively) using a
for statement as follows:factorial = 1;
for ( counter = number; counter >= 1; counter-- )factorial *= counter;
4
Recursion …
5
Recursion …
6
Recursion …
7
Recursion …
The conversion specifier %ld is used to print long values.
Unfortunately, the factorial function produces large
values so quickly that even long int does not help us print
many factorial values before the size of a long intvariable is exceeded.
As we’ll explore in the exercises, double may ultimately
be needed by the user desiring to calculate factorials of
larger numbers.
This points to a weakness in C (and most other procedural
programming languages), namely that the language is not
easily extended to handle the unique requirements of various
applications.8
Recursion …
The Fibonacci series 0, 1, 1, 2, 3, 5, 8, 13, 21, …
begins with 0 and 1 and has the property that each
subsequent Fibonacci number is the sum of the previous
two Fibonacci numbers.
The Fibonacci series may be defined recursively as
follows:
fibonacci(0) = 0fibonacci(1) = 1fibonacci(n) = fibonacci(n – 1) + fibonacci(n – 2)
Figure 5.15 calculates the nth Fibonacci number
recursively using function fibonacci.9
Example Using Recursion: Fibonacci Series
10
Example Using Recursion: Fibonacci Series …
11
Example Using Recursion: Fibonacci Series …
12
Example Using Recursion: Fibonacci Series …
13
Example Using Recursion: Fibonacci Series …
14
Example Using Recursion: Fibonacci Series …
Each level of recursion in the fibonacci function has a
doubling effect on the number of calls; i.e., the number of
recursive calls that will be executed to calculate the nth
Fibonacci number is on the order of 2n.
This rapidly gets out of hand.
Computer scientists refer to this as exponential complexity.
Problems of this nature humble even the world’s most
powerful computers!
Complexity issues in general, and exponential complexity in
particular, are discussed in detail in the upper-level computer
science curriculum course generally called “Algorithms”.15
Example Using Recursion: Fibonacci Series …
A string of binary digits is good if there is no two
consecutive 1s in that string. Write a program to
input the integer number n, and then count the
number of distinct good strings with length of n.
16
Question
Answer (Iteration)
int main(){
int n;
scanf("%d",&n);
int a=3, b=2, c=0;
if(n==1)
c=2;
if(n==2)
c=3;
for(int i=3; i<=n; i++){
c=a+b;
b=a;
a=c;
}
printf("%d",c);
return 0;
}17
Question …
Answer (Recursion)
int f1(int);
int main(){
int n;
scanf("%d",&n);
printf("%d",f1(n));
return 0;
}
int f1(int n){
if(n==1)
return (2);
else if(n==2)
return (3);
else
return ( f1(n-1) + f1(n-2) );
}
18
Question …
In the previous sections, we studied two functions that can easily be
implemented either recursively or iteratively.
Both iteration and recursion are based on a control structure: Iteration
uses a repetition structure; recursion uses a selection structure.
Both iteration and recursion involve repetition: Iteration explicitly
uses a repetition structure; recursion achieves repetition through
repeated function calls.
Iteration and recursion each involve a termination test: Iteration
terminates when the loop-continuation condition fails; recursion
terminates when a base case is recognized.
Both iteration and recursion can occur infinitely: An infinite loop
occurs with iteration if the loop-continuation test never becomes
false; infinite recursion occurs if the recursion step does not reduce
the problem each time in a manner that converges on the base case.19
Recursion vs. Iteration
Recursion has many negatives.
It repeatedly invokes the mechanism, and consequently the
overhead of function calls.
This can be expensive in both processor time and memory space.
Each recursive call causes another copy of the function (actually
only the function’s variables) to be created; this can consume
considerable memory.
Iteration normally occurs within a function, so the overhead of
repeated function calls and extra memory assignment is omitted.
So why choose recursion?
20
Recursion vs. Iteration …
21
Recursion vs. Iteration …
22
Recursion vs. Iteration …
The Tower of Hanoi or Towers of Hanoi , also called the Tower of
Brahma or Towers of Brahma, is a mathematical game or puzzle.
It consists of three rods, and a number of disks of different sizes
which can slide onto any rod. The puzzle starts with the disks in a
neat stack in ascending order of size on one rod, the smallest at the
top, thus making a conical shape.
Only one disk may be moved at a time.
Each move consists of taking the upper disk from one of the rods and
sliding it onto another rod, on top of the other disks that may already
be present on that rod.
No disk may be placed on top of a smaller disk.
23
Tower of Hanoi
24
Tower of Hanoi …
At the top level, we will want to move the entire tower, so we
want to move n disks from rod A (source) to rod C (destination).
We can break this into three basic steps.
1. Move n-1 disks from rod A (source) to rod B (spare), using rod
C (destination) as a spare. How do we do this? By recursively
using the same procedure. After finishing this, we'll have all the
disks smaller than disk n on rod B.
2. Now, with all the smaller disks on the spare rod, we can move
disk n from rod A (source) to rod C (destination).
3. Finally, we want move n-1 disks from rod B (spare) to rod C
(destination). We do this recursively using the same procedure
again.25
Tower of Hanoi …
Pseudocode:
FUNCTION MoveTower(disk, source, dest, spare)
IF disk == 1, THEN:
move disk from source to dest
ELSE:
MoveTower(disk - 1, source, spare, dest) // Step 1
move disk from source to dest // Step 2
MoveTower(disk - 1, spare, dest, source) // Step 3
END IF26
Tower of Hanoi …
27
Tower of Hanoi …
void hanoi(int x, char from, char to, char aux)
{
if(x==1)
printf ("Move Disk From %c to %c\n", from, to);
else
{
hanoi (x-1, from, aux, to);
printf ("Move Disk From %c to %c\n", from, to);
hanoi (x-1, aux, to, from);
}
}
28
Tower of Hanoi …
int main(void)
{
int disk;
int moves;
printf ("Enter the number of disks you want to play with:");
scanf ("%d", &disk);
moves = pow(2, disk) - 1;
printf ("\nThe No. of moves required is=%d \n”, moves);
hanoi (disk, 'A', 'C', 'B');
}