4 - Recursion - V2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 62

Recursion

Tanvir Ahmed, PhD


Recursion
• A powerful problem solving strategy
• Definition:
– If the body of a function call the function itself.
• As you can call a function fun1() from a function fun2(), you
are also allowed to call fun1() from fun1().
• What can be the potential problem?:
– Let’s say you are calling fun1 from the body of fun1
– Wouldn’t it be like an infinite loop?
– How can it stop?
– So, inside the body of your function you must put something that
must prevent it to call the function again (i.e., must not result in
a recursive call to prevent to fall in infinite loop).
Example1
void rec2(int x)
{
if (x==0)
return; //this breaking condition will result in poping the function call stack

rec2(x-1);

printf("%d ", x); //this line (including the value of x) is kept in the stack for each call of rec(x-1) in the above line
}

void rec1(int x) int main()


{ {
if (x==0) printf("Calling rec1: ");
return; //breaking condition rec1(10);

printf("%d ", x); //prints first then recursion printf("\nCalling rec2: ");
rec1(x-1); rec2(10);
} }
Output:
Calling rec1: 10 9 8 7 6 5 4 3 2 1
Calling rec2: 1 2 3 4 5 6 7 8 9 10
Explaining Example 1
• Can’t you print the same numbers using a
loop?
Function rec1:
for(i=10; i>0; i--)
printf(“%d” , i);
Function rec2:
for(i=1; i<=10; i++)
printf(“%d” , i);
Analyze rec1 of Example 1
void rec1(int x)
{
if (x==0)
return; //breaking condition

printf("%d ", x); //prints first then recursion


rec1(x-1);
}
• It is a very simple example of recursion.
• The printf prints the value of x at a particular call and then a recursive call is made with x-1, which means
the value of X is decreased by one for the next call.
• As soon as the value of x is 0, the function return to most recent call and prevent it to make the recursive
call again.
• As there is no statement after the recursive call, noting to be kept to execute later.
• call: rec1(10) from main function.
• printf("%d ", 10); call: rec1(9);
• printf("%d ",9); call: rec1(8)
• printf("%d ", 8); call: rec1(7)
• printf("%d ", 7); call: rec1(6)
• printf("%d ", 6); call: rec1(5)
• printf("%d ", 5); call: rec1(4)
• printf("%d ", 4); call: rec1(3)
• printf("%d ", 3); call: rec1(2)
• printf("%d ", 2); call: rec1(1)
• printf("%d ", 1 ); call: rec1(0)
• return to previous call and so on. Actually the function complete its full task after returning to all previous calls. But nothing
was pending for each call in this example
• So, the output is: 10 9 8 7 6 5 4 3 2 1
• Why 0 is not in the output?
Analyze rec2 of Example 1
void rec2(int x)
{
if (x==0)
return; // it is the breaking condition of the recursion call.
rec2(x-1);
printf("%d ", x);
}
• rec2(x-1) is preventing the printf to work while performing the operation of a
particular call.
– So, the lines after rec2(x-1); are kept in a stack.
• call: rec2(10) ->push: printf("%d ", 10);
• call: rec2(9) ->push: printf("%d ", 9);
• call: rec2(8) ->push: printf("%d ", 8);
• call: rec2(7) ->push: printf("%d ", 7);
• call: rec2(6) ->push: printf("%d ", 6);
• call: rec2(5) ->push: printf("%d ", 5);
• call: rec2(4) ->push: printf("%d ", 4);
• call: rec2(3) ->push: printf("%d ", 3);
• call: rec2(2) ->push: printf("%d ", 2);
• call: rec2(1) ->push: printf("%d ", 1);
• call: rec2(0) -> return and keep popping.
• So, the output is: 1 2 3 4 5 6 7 8 9 10
• Why 0 is not in the output?
Example2: Power calculation
• Calculating power be
• It means you need to multiply b (e times). b*b*b*… e times
• Loop based iterative solution:
int Power(int base, int exponent){
long result = 1;

while (exponent != 0)
{
result *= base;
--exponent;
}
return result;
}

• How can you use recursion to do it?


Example2
// Pre-conditions: e is greater than or equal to 0.
// Post-conditions: returns be.
int Power(int base, int exponent) {

if ( exponent == 0 )
return 1;
else
return (base*Power(base, exponent-1));
}

Say we were trying to evaluate the expression:


• Power(5, 2)
• Power(5,2) returns 5*Power(5,2-1) = 5*Power(5,1)
• To evaluate this expression we must evaluate:
• Power(5,1) returns 5*Power(5, 0)
• Finally, we have:
• Power(5,0) returns 1.
• Thus, Power(5,1) returns 5*1, which is 5.
• Finally, Power(5,2) returns 5*Power(5,2-1) = 5*5 = 25,
• and we are done.
General structure of a Recursive Functions
• We can see that in recursion in general:
– when we have a problem, we want to break it down into chunks,
where one of the chunks is a smaller version of the same problem.
• In the case of Power, we utilized the fact that
– xy = x * xy-1, and realized that xy-1 is in essence an easier version of
the original problem.
• We break down our original problem enough that our sub-problem is
quite easy to solve.
– At this point, rather than making another recursive call, directly
return the answer, or complete the task at hand.
• So, ideally, a general structure of a recursive function has a couple
options:
– Break down the problem further, into a smaller subproblem
– OR, the problem is small enough on its own, solve it.
• When we have two options, we often use an if statement. This is
typically what is done with recursion.
General structure of a Recursive Functions
• Here are the two general constructs of recursive functions:
Construct 1
if (terminating condition) {
DO FINAL ACTION
}
else {
Take one step closer to terminating condition
Call function RECURSIVELY on smaller subproblem
}
Construct 2
if (!(terminating condition) ) {
Take a step closer to terminating condition
Call function RECURSIVELY on smaller subproblem
}

• Typically, functions that return values take on the first construct,


• while void recursive functions use the second construct.
• Note that these are not the ONLY layouts of recursive programs, just common
ones.
Example using construct 1
• Let’s write a function that takes in one positive integer
parameter n, and returns the sum 1+2+...+n. (You probably
did this is C)
• Can you write the iterative solution that you have done in C?

// Pre-condition: n is a positive integer.


// Post-condition: Function returns the sum 1+2+...+n
int Triangle_Number(int n) {
int index, sum = 0;
for (index=1; index <=n; index++)
sum = sum + index;

return sum;
}
Example using construct 1
• Let’s write the recursive solution of the example:
• Step 1: We need to solve this problem is such a way that part of the
solution is a sub-problem of the exact same nature.
• Let f(n) denote the value 1+2+3+...+n
• Using our usual iterative logic, we have:
f(n) = 1 + (2 + 3 + ... + n)
• But, 2+3+... + n IS NOT a sub-problem of the form 1+2+...+n.
• But, let’s try this:
f(n) = 1 + 2 + ... + n = n + (1 + 2 + ... + (n-1))
f(10) = 1 + 2 + ... + 10 = 10 + (1 + 2 + ... + 9) = 10 + f(9)
• So, here we have gotten the expression 1 + 2 + ... + (n-1) which IS a
sub-problem we were looking for.
• Hence, we have
f(n) = 1 + 2 + ... + n = n + (1 + 2 + ... + (n-1)) = n + f(n-1)
Example using construct 1
• If we look at the construct 1, the first thing we need to determine is
a terminating condition.
– We know that f(0) = 0, so our terminating condition can be n=0.
• Furthermore, our recursive call needs to be returning an expression
for f(n) in terms of f(k), for some k<n.
– In this case, we just found that f(n) = n + f(n-1). So, now we can
write our function: can you write it?

// Pre-condition: n is a positive integer.


// Post-condition: Function returns the sum 1+2+...+n
int Triangle_Number(int n) {

if ( n == 0 )
return 0;
else
return (n + Triangle_Number(n-1));
}
Two Other Classic Examples that Use Construct #1
• For positive integers n, n! (read, “n factorial”), is defined as follows:
n! = 1x2x3x4x…xn
• What is a factorial?
– 4! = 4 * 3 * 2 * 1 = 24
– In general, we can say:
– n! = n * (n-1) * (n-2) * … * 2 * 1
• Also, 0! = 1(just accept it!)
• Mathematically, factorial is already defined recursively (Note that each factorial is
related to a factorial of the next smaller integer)
• 4! = 4*3*2*1 = 4 * (4-1)! = 4 * (3!)
• Another example:
– 10! = 10*9*8*7*6*5*4*3*2*1
– 10! = 10 * (9!)
• So:
– n! = n*(n-1)!
– What would be the stopping condition?
– We let 0! = 1;
• Why don’t you write the recursive function?
Two Other Classic Examples that Use Construct #1
• So, the recursive code for factorial would look like this:

#include <stdio.h>
void Fact(int n);
int main(void)
{
int factorial = Fact(10);
printf(“%d\n”, factorial);
return 0;
}

//Here’s the Fact Function


int Fact (int n)
{
if (n == 0) return 1;
else
return (n * Fact(n-1));
}

This program prints the result of 10*9*8*7*6*5*4*3*2*1


Which is:3628800
Slides courtesy: Prof Jonathon’s slides on recursion
Slides courtesy: Prof Jonathon’s slides on recursion
Two Other Classic Examples that Use Construct #1
• Fibonacci numbers are defined recursively, thus,
coding them is quite easy, based on the original
mathematical definition:
• F0 = 0, F1 = 1, Fn = Fn-1 + Fn-2, for all integers n > 1.
• Here is a list:
– 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377,
610,, ...
int fib(int n) {

if (n <= 1)
return n;
else
return fib(n-1) + fib(n-2);
}
Illustration of the Fibonacci recursion process
using recursion tree
Example using construct 2
Construct 2
if (!(terminating condition) ) {
Take a step closer to terminating condition
Call function RECURSIVELY on smaller subproblem
}
• Let’s write a function to generate TIP chart:
• Write a function that takes in the lowest dollar value and highest dollar value on
the chart. You know the TIP rate. The method header would look like the:
// The function prints out a chart with the appropriate tips
// for meals ranging from first_val to last_val number of
// dollars, for every whole dollar amount. Both parameters
// must be positive integers.
void Tip_Chart (int first_val, int last_val)
• Now, let’s consider writing this function recursively.
• First, we need to determine a terminating condition.
– if the lowest dollar amount is greater than the highest dollar amount, then the
chart is empty and we are done.
• Next, we need to figure out how to break down our task into two steps: one that
does part of the job, and secondly a recursive step.
Example using construct 2
• Tip Chart:
• What would be the first print out and what is next?
– It is clear that the first value we have to print of the chart is associated with
the lowest dollar value, since that must appear on the chart first.
– Printing out this line of the tip chart can be the part of the job we
accomplish.
• Now, are we left with a sub-problem of the same nature?
– Yes! We simply now need to print a tip chart from the lowest dollar value+1
to the highest dollar value.
Example using construct 2
#define TIP_RATE 0.15

// Pre-condition: Both parameters are integers with the first one being less than or equal to the
second one.
// Post-condition: A tip chart will be printed out, with a row for each dollar amount ranging in
between the value of the two parameters.
void Tip_Chart (int first_val, int last_val)
{

if ( !(first_val > last_val) ) {


printf("On a meal of $%d", first_val);
printf(" you should tip $%lf\n", first_val*TIP_RATE);
Tip_Chart(first_val + 1, last_val);
}
}

int main () On a meal of $1 you should tip $0.150000


{ On a meal of $2 you should tip $0.300000
On a meal of $3 you should tip $0.450000
Tip_Chart(1,10);
On a meal of $4 you should tip $0.600000
On a meal of $5 you should tip $0.750000
} On a meal of $6 you should tip $0.900000
On a meal of $7 you should tip $1.050000
On a meal of $8 you should tip $1.200000
On a meal of $9 you should tip $1.350000
On a meal of $10 you should tip $1.500000
Practice problem
• Write a recursive function that takes a string and
the length of the string in parameters, then print
the string in reverse order.
• The prototype should look like this:
• void print_reverse(char string[], int n)
• If “hello” and 5 is passed, it should print “0lleh”
• What position should be printed first?
– string[n-1]
• What would be the breaking condition?
– If n==1
Solving using construct 1

// Pre-condition: string is a string of length n or greater.


// Post-condition: Prints out the first n characters of string in reverse order.
void print_reverse(char string[], int n) {

// Only one character to print, so print it!


if (n == 1)
printf("%c", string[0]);

// Solve the problem recursively: print the last character, then reverse
// the substring without that last character.
else {
printf("%c", string[n-1]);
print_reverse(string, n-1);
}
}
Solving using construct 2

void printReverse(char word[], int length)


{
if (length > 0)
{
printf(“%c”, word[length-1]);
printReverse(word, length-1);
}
}
Practice Problem
• Write a recursive function that:
• Takes in two non-negative integer parameters
• Returns the product of these parameters
– But it does NOT use multiplication to get the
answer
– So if the parameters are 6 and 4
– The answer would be 24
• Multiplication MxN is actully adding M for N times
• 6*4 = adding 6, 4 times.
• So, 6*4 = 6 + 6 + 6 + 6
• Now write the function.
Practice problem-solution
// Precondition: Both parameters are non-negative integers.
// Postcondition: The product of the two parameters is returned.
int Multiply(int first, int second)
{
if (( second == 0 ) || ( first = 0 ))
return 0;
else
return (first + Multiply(first, second-1));
}

How can you modify it to work for negative number?


int Multiply (int first, int second) { -Example: if you calculate 4 * -3, the program converts
the result to negative and make -3 to +3 and then use
if ( second < 0 ) the usual recursion in the else statement
return -Multiply(first,-second); - Example: if you calculate -4 * 3, the program
else if ( first < 0 ) converts the result to negative and make -4 to +3
and then use the usual recursion in the else
return -Multiply(-first, second); statement
else if (( second == 0 ) || ( first = 0 )) - Example: if you calculate -4 * -3, the program
return 0; converts the result to negative and make -3 to +3
- In the next call, it converts the result to
else negative again (which makes the result
return (first +Multiply(first, second-1)); positive) and converts -4 to +4. Then it uses
the usual recursion in the else statement
}
More exercises
• 1) Write a recursive function that determines the
nth Lucas number. Here is the definition of the
Lucas numbers:

• L1 = 1, L2 = 3, Ln = Ln-1 + Ln-2, for all integers n > 2.



• // Pre-condition: n > 0
• // Post-condition: Returns the nth Lucas number, Ln.

int Lucas(int n);


nth Lucas number
// n'th Lucas number
#include <stdio.h>

// recursive function
int lucas(int n)
{
// Base cases
if (n == 1)
return 1;
else if (n == 2)
return 3;
else
return lucas(n - 1) + lucas(n - 2);
}

// Driver Code
int main()
{
int n = 9;
printf("%d", lucas(n));
return 0;
}
Try this
• How can you use recursion to convert and
print Decimal to Binary?
• Remember the steps: division and reminder
technique.
• The reminders should be printed from bottom
to top.
• Next slide is copied from Number system slide
to remind you about the steps
• Converting from base 10 to a new base
(division- remainder technique)
11710 = ?2

Step Operation Result (n/base) Remainder (n%base)

Step 1 117 / 2 58 1

Step 2 58 / 2 29 0

Step 3 29/ 2 14 1

Step 4 14 / 2 7 0

Step 5 7/2 3 1

Step 6 3/2 1 1
Read reverse order 11101012

2/13/2020 Tanvir Ahmed 31


Decimal to Binary

void dectobin(int n) {

if (n < 2)
printf("%d", n);

else {
dectobin(n/2);
printf("%d", n%2);
}
}
Towers of Hanoi
• Problem:
• we have:
• three rods ( or tower)
• n disks in the left most tower. The disks are arranged with
the largest diameter disks at the bottom

• Some monk has the daunting task of moving disks from one
tower to another tower
– Often defined as moving from Tower #1 to Tower #3
• Tower #2 is just an intermediate pole

– He can only move ONE disk at a time


– And he MUST follow the rule of NEVER putting a bigger disk on
top of a smaller disk
Towers of Hanoi
• Steps:
• Take an example for 2 disks :
• Let rod 1 = 'A', rod 2 = 'B', rod 3 = 'C'.

• Step 1 : Shift first disk from 'A' to 'B'.


• Step 2 : Shift second disk from 'A' to 'C'.
• Step 3 : Shift first disk from 'B' to 'C'.

• The pattern here is :


• Shift 'n-1' disks from 'A' to 'B'.
• Shift last disk from 'A' to 'C'.
• Shift 'n-1' disks from 'B' to 'C'.
illustration for 3 disks :
illustration for 3 disks :
Towers of Hanoi
• Input : 2
Output :
Disk 1 moved from A to B
Disk 2 moved from A to C
Disk 1 moved from B to C

• Input : 3
Output :
Disk 1 moved from A to C
Disk 2 moved from A to B The pattern here is :
Disk 1 moved from C to B Shift 'n-1' disks from 'A' to 'B'.
Disk 3 moved from A to C Shift last disk from 'A' to 'C'.
Shift 'n-1' disks from 'B' to 'C'.
Disk 1 moved from B to A
Disk 2 moved from B to C
Disk 1 moved from A to C
Towers of Hanoi
#include <stdio.h>

void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod)


{
if (n == 1)
{
printf("\n Move disk 1 from rod %c to rod %c", from_rod, to_rod);
return;
}
towerOfHanoi(n-1, from_rod, aux_rod, to_rod);
printf("\n Move disk %d from rod %c to rod %c", n, from_rod, to_rod);
towerOfHanoi(n-1, aux_rod, to_rod, from_rod);
}

int main()
{
int n = 4; // Number of disks
towerOfHanoi(n, 'A', 'C', 'B'); // A, B and C are names of rods
return 0;
}
Output:
Move disk 1 from rod A to rod B
Move disk 2 from rod A to rod C
Move disk 1 from rod B to rod C
Towers of Hanoi
Move disk 3 from rod A to rod B
Move disk 1 from rod C to rod A For n disks, total 2n – 1 moves are required.
Move disk 2 from rod C to rod B
Move disk 1 from rod A to rod B eg: For 4 disks 24 – 1 = 15 moves are required.
Move disk 4 from rod A to rod C
Move disk 1 from rod B to rod C For n disks, total 2n-1 function calls are made.
Move disk 2 from rod B to rod A
Move disk 1 from rod C to rod A eg: For 4 disks 24-1 = 8 function calls are made.
Move disk 3 from rod B to rod C
Move disk 1 from rod A to rod B
Move disk 2 from rod A to rod C
Move disk 1 from rod B to rod C
Illustration of the
recursion
Fast Exponent
int Power(int base, int exponent) {

if ( exponent == 0 )
return 1;
else
return (base*Power(base, exponent-1));
}
• Our recursive power function works just fine
• But, it becomes VERY slow for large exponents
– If the exponent was 10,000, that would be 9,999
multiplications!
• How can we do better?
– Rememer the laws of exponents:
• 28 = 24 * 24
• Now 24 = 22 * 22
• And 22 = 2 * (2)
– So: 2*(2) = 4, 4*(4) = 16, 16*(16) = 256 = 28
– So we’ve calculated 28 using only three multiplications
– MUCH better than 7 multiplications
Fast Exponent
• So, we see that bn = bn/2 * bn/2
• It will be log n number of multiplication (much better than n
multiplication)
• But can you guess what problem we have here: bn = bn/2 * bn/2
• It works when n is even. How about if n is not even?
• See: 29= 24*24*2
• So, we need to handle this case. We can say:

• Also note that this method relies on integer division.


– if n is 9, then n/2 = 4
• So, can you write the code?
Fast Exponent
int powerB(int base, int exp)
{
if (exp == 0)
return 1;
if (exp == 1)
return base;
if (exp%2 == 0) //if exp is even
return powerB(base*base, exp/2);
else //if exp is odd
return powerB(base*base, exp/2) *base;
}

int main()
{
printf("%d", powerB(2,5));

return 0;
}
Let us try to find the result of f(4) for
the following recursive function using
recursion tree
int f(int n)
{
int ans;
int i;
if(n<3)
return n;
ans = f(n/2);
for(i=0; i<n; i++)
ans += f(i);
return ans;
}
int f(int n)
{
int ans;
int i;
if(n<3)
return n;
ans = f(n/2);
for(i=0; i<n; i++)
ans += f(i);
return ans;
}
More Recursion: Permutations
• The permutation problem is as follows:
• Given a list of items,
– list all the possible orderings of those items.
– The items can be numbers or letters or other object
• For example: all the permutations of 0,1,2:
• 0, 1, 2
• 0, 2, 1
• 1, 0, 2
• 1, 2, 0
• 2, 0, 1
• 2, 1, 0.
• Another example: All the permutations of the letters CAT:
CAT ACT TAC
CTA ATC TCA

• How can we write a program to generate these permutations?


Permutations
• There are several different permutation algorithms, but
since recursion an emphasis of the course, a recursive
algorithm to solve this problem will be presented.
• The permutation algorithm:
– We want to list all the permutations of “CAT”
– So, let’s split our task into 3 groups of
permutations.
a) Permutations that start with C
b) Permutations that start with A
c) Permutations that start with T

CAT ACT TAC


CTA ATC TCA
Permutations
Permutations that start with C:
 Think about recursion and how can we reduce the
problem to a smaller problem of same form
 Permutations starts with C are 3-character strings
that form by putting C in the beginning of all
permutations of “AT”
 So, it means we need to do another permutation,
which is smaller and it should be in the same form!
CAT
CTA

 So, two things to note here:


 We will use recursion for generating the
permutations
 We need to do it for each of the starting letter.
Permutations
 As we have split our task in the 3 groups as we
have 3 letters in CAT.
 We will need 3 recursive calls, one for each letter
 If we were permuting the letters of the word
“science”, we could need
 Eight recursive calls, one for each possible starting
letter.
 So, we will need a for loop in our algorithm:
for (each possible starting letter)
{
list all permutations that start with that letter
}
Permutations
 What would be the terminating condition for your
recursion?
 If we have only 0 or 1 element, there is nothing to
permute
 We will use 0 as the terminating condition
 It means when there is only 0 element left, we break our
recursion
 The function prototype should look like this:
// Pre-condition: str is a valid C String, and k is non-negative and
// less than or equal to the length of str.
// Post-condition: All of the permutations of str with the first k
// characters fixed in their original positions are
// printed. Namely, if n is the length of str, then
// (n-k)! permutations are printed.
void RecursivePermute(char str[], int k);

So k refers to the first k characters that are fixed in their original


positions
Permutations
 What would be the terminating condition for your recursion?
 Remember, k refers to the first k characters that are fixed
 So, we should terminate when k is equal to the length of the string,
str
 So, when the terminating condition occurs, we simply want to print
out our permutation
 If the terminating condition is not met,
 We use a for loop that tries each character at index k.
 The main loop will look like this:
for (j=k; j<strlen(str); j++) {
ExchangeCharacters(str, k, j);
RecursivePermute(str, k+1);
ExchangeCharacters(str, j, k);
}
- Now how do we get different characters (the ‘C’, the ‘A’, and the ‘T’) at the
first position?
- C is the first character in the word CAT
- So how do we make ‘A’ become the first character
Permutations
for (j=k; j<strlen(str); j++) {
ExchangeCharacters(str, k, j);
RecursivePermute(str, k+1);
ExchangeCharacters(str, j, k);
}

• ExchangeCharacters function:
– This function will take in the string (str) and it will swap
two characters within that string.
– The character at index k will swap with the one at index j

// Pre-condition: str is a valid C String and i and j are valid indexes to that
string.
// Post-condition: The characters at index i and j will be swapped in str.
void ExchangeCharacters(char str[], int i, int j) {
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
Permutations
for (j=k; j<strlen(str); j++) {
ExchangeCharacters(str, k, j);
RecursivePermute(str, k+1);
ExchangeCharacters(str, j, k);
}

• ExchangeCharacters function:
– Remember: We need to find all permutations
with C as the first character, A as the first, and
with T as the first (for “CAT”)
– The ExchangeCharacters function swaps the two
characters at the indices passed in.
– We then recursively call the permute function
– Then we swap the characters back to their spots.
Permutations
void RecursivePermute(char str[], int k) {

int j;
// Base-case: Since all letters are fixed, we can ONLY print what's stored in str.
if (k == strlen(str))
printf("%s\n", str);

else {
// Loop through each possible starting letter for index k, the first index for which we have a choice.
for (j=k; j<strlen(str); j++) {
// Place the character stored in index j in location k.
ExchangeCharacters(str, k, j);

// Print out all of the permutations with that character just chosen above fixed.
RecursivePermute(str, k+1);

// Put the original character that used to be there back in its place.
ExchangeCharacters(str, j, k);
}
}
}
Permutation
void RecursivePermute(char str[], int k) {

int j;
// Base-case: Since all letters are fixed, we can ONLY print what's stored in str.
if (k == strlen(str))
printf("%s\n", str);

• Let’s discuss the code:


– We sent our string and k to this function.
– From the main function we just passed k=0
– Remember, k represents the first k characters that are fixed at
their spots
– So for the first time in our example we passed:
• CAT and k=0
– The base case says if k becomes the length of our string, it
means all characters are fixed
• In such case no permutation is needed and we print out the resulting
string
Permutation
void RecursivePermute(char str[], int k) {
// previous code here
else {
// Loop through each possible starting letter for index k, the first index for which
we have a choice.
for (j=k; j<strlen(str); j++) {
// // our code here

• Let’s discuss the code:


– So, all other cases it means if all characters are
not fixed yet
• We need to permute more
• We have to try the character at position k
• So, we go to the loop
Permutation
• In the loop it iterates and use the possible characters
that can go into index k
• Remember, k refers to the number of fixed positions.
– If k is 2, it means index 0 and index 1 are fixed
– Then the first non-fixed location is index 2, so the valu eof
k is 2

for (j=k; j<strlen(str); j++) {


// Place the character stored in index j in location k.
ExchangeCharacters(str, k, j);

// Print out all of the permutations with that character just chosen above fixed.
RecursivePermute(str, k+1);

// Put the original character that used to be there back in its place.
ExchangeCharacters(str, j, k);
}
Permutation
• For all possible chracters tht could be placed at
index k:
– ExchangeCharacters (str, k, j)
– It means swap the charcaters at index k and j
– Meaning, try all possible (remaining) values at index k

for (j=k; j<strlen(str); j++) {


// Place the character stored in index j in location k.
ExchangeCharacters(str, k, j);

// Print out all of the permutations with that character just chosen above fixed.
RecursivePermute(str, k+1);

// Put the original character that used to be there back in its place.
ExchangeCharacters(str, j, k);
}
Permutation
• For all possible characters at index k:
– So for our example for the first time:
• Input was CAT for the starting and k = 0;
• This loop would run three times(length of CAT=3)
– Each time, the first line would try each character at index 0
– It means C will be at 0, then A will be at 0 and then T will be at 0

for (j=k; j<strlen(str); j++) {


// Place the character stored in index j in location k.
ExchangeCharacters(str, k, j);

// Print out all of the permutations with that character just chosen above fixed.
RecursivePermute(str, k+1);

// Put the original character that used to be there back in its place.
ExchangeCharacters(str, j, k);
}
Permutation
• So, the for loop iterates three times (for CAT)
– First line of code makes each letter the first spot of the
string
– The second line then recursively calls the function
• The arguments are string (updated with a new, 1st character)
• And the new value of k (referring to the #of Fixed spots)
– Third and final line of code simply switches back he
characters that we swapped with the first line of code (of
the for loop)
for (j=k; j<strlen(str); j++) {
// Place the character stored in index j in location k.
ExchangeCharacters(str, k, j);

// Print out all of the permutations with that character just chosen above fixed.
RecursivePermute(str, k+1);

// Put the original character that used to be there back in its place.
ExchangeCharacters(str, j, k);
}
Permutation
• The full code is available here:
https://www.cs.ucf.edu/courses/cop3502/spr2012
/programs/recursion/permute.c
- A tracing code is available here:
https://www.cs.ucf.edu/courses/cop3502/spr2012
/programs/recursion/permute2.c

- Prof Arup’s note on permutation(self study):


http://www.cs.ucf.edu/~dmarino/ucf/transparency
/cop3502/lec/RecursionPermutations.doc
References
• Tower of Hanoi: https://www.geeksforgeeks.org/c-program-for-
tower-of-hanoi/
• Arup Guha’s notes:
– http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/lec/Rec
ursionIntro.doc
– http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/lec/Rec
ursionTowers.doc
– http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/lec/Rec
ursionFastExp.doc
– http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/lec/Rec
ursionFloodFill.doc
– http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/lec/Rec
ursionPermutations.doc
• Many example functions in one c code:
http://www.cs.ucf.edu/~dmarino/ucf/transparency/cop3502/samp
leprogs/recursion.c

You might also like