recursive programming (i) - eecs.wsu.eduaabnousi/cpts121/lectures/l20_recursion_1.pdf · problem...

36
Recursive Programming (I) Lecture 20 CptS 121 – Summer 2016 – Armen Abnousi

Upload: buique

Post on 01-Sep-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

Recursive Programming (I)

Lecture 20

CptS 121 – Summer 2016 – Armen Abnousi

Function calls and order of operation

• Within a block of code, the control is sequential.

• i.e. running the commands one by one, in the order

they appear.

• Calling a function (b), inside a block of code (fun a):

pauses the operation of the current block (a),

Moves the control to the callee function (b),

Executes the callee function (b) until it finishes (returns the

output or ends the block)

Control returns to the caller function (a)

Resumes operation in (a) from where it paused

Function calls and order of operation

int main()

{

double num;

fun();

return 0;

}

1

2

3

4

Order of operation

Function calls and order of operation

int main()

{

double num;

fun();

return 0;

}

void fun()

{

int inFun;

printf(“inside function”);

}

1

2

3

4

Order of operation

5

6

10

Function calls and order of operation

int main()

{

double num;

fun();

return 0;

}

void fun()

{

int inFun;

printf(“inside function”);

}

1

2

3

4

Order of operation

5

6

10

11

Function calls and order of operation

• There might be more than one function call:

(Each box represents a function. Function name is written

above the box. Inside the box are some statements from

the function).

funa();

main()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Function calls and order of operation

• There might be more than one function call:

funa();

main()

funb();

funa()

funb()

Recursion

• We might have a cycle of function calls!

Function funa() might call itself

Function funa() might call funb() while funb() calls funa()

• This is called recursion.

• When a function calls itself a copy of the function starts

running with new local variables and input parameters

Recursion and local variables

• Function funa() is calling itself. Recursion!

funa(1);

main()

funa(a+b);

funa(a)

b = 1

Recursion and local variables

• Function funa() is calling itself. Recursion!

funa(1);

main()

funa(a+b);

funa(a)

b = 1

Recursion and local variables

• Function funa() is calling itself. Recursion!

funa(1);

main()

funa(a+b);

funa(a)

b = 1

a b

Memory: 1 1

Data space for funa()’s

first call

Recursion and local variables

• Function funa() is calling itself. Recursion!

funa(1);

main()

funa(a+b);

funa(a)

b = 1

a b a b

Memory: 1 1 2 ?

Data space for funa()’s

first call

funa(a+b);

funa(a)

b = 1

Data space for funa()’s

second call

Recursion and local variables

• Function funa() is calling itself. Recursion!

funa(1);

main()

funa(a+b);

funa(a)

b = 1

a b a b

Memory: 1 1 2 1

Data space for funa()’s

first call

funa(a+b);

funa(a)

b = 1

Data space for funa()’s

second call

Calling funa() with argument 3

Recursion – points to remember

1. Recursive calls to a function use different areas in the

memory. Local variables for different calls might have

different values!

• For the first call we had a = 1, b = 1. For the second call

we had a = 2, b = 1.

2. There need to be at least one special case which

doesn’t result in calling the recursive function again!

• When will the series of calls to funa() stop in our

previous slide?

• There needs to be some type of selection structure

somewhere in funa, that if its condition is met then

doesn’t call funa anymore, but rather returns to the

calling function.

When do we use recursion?

If:

One or more simpler cases of the problem have a straight-

forward solution

And other cases can be broken down to smaller

subproblems that are closer to the simple case

then recursive programs can be helpful.

How do we use recursion?

If:

One or more simpler cases of the problem have a straight-

forward solution

And other cases can be broken down to smaller

subproblems that are closer to the simple case

then recursive programs can be helpful.

• For each simple case return the answer that is already

known

• For each more complicated case, partially solve the

problem and call the recursive function to solve the

remaining part of it.

How do we use recursion?

• For each simple case return the answer that is already

known

• For each more complicated case, partially solve the

problem and call the recursive function to solve the

remaining part of it.

if this is a simple case

solve it

else

redefine the problem using recursion

Simple case is checked by

the terminating condition

(i.e. no more recursions)

Example – Counting a letter in a string

• Given a string s and a letter c, we want to count how

many times the letter appears in the string.

Example – Counting a letter in a string (page 525)

• Given a string s and a letter c, we want to count how

many times the letter appears in the string.

• Solution:

If the string length is zero then the letter appears 0 times.

If the string length is n (≠0), then

• if the first character is not c, then we can compute

the count by solving the problem with the substring

that starts with our second letter

• If the first character is c, then we can compute the

count by adding 1 to the count in the substring that

starts with our second letter.

Example – Counting a letter in a string (page 525)

int countLetter(char query, char str[])

{

int count = 0;

if (strlen(str) == 0) /* simple case */

count = 0;

else /* redefine using recursion */

{

if (str[0] == query)

count = 1 + countLetter(query, &str[1]);

else

count = 0 + countLetter(query, &str[1]);

}

return count;

}

Example – Counting a letter in a string (page 525)

int main()

{

char str[] = "These are our sentences!";

printf("%d\n", countLetter('s', str));

return 0;

}

Example - factorial

• Write a program that given an integer n, computes n!.

We have written an iterative version of this program

before, now we want to write a recursive version.

Example - factorial

long factorial(int n)

{

long result = 0;

if (n == 0) /* simple case */

result = 1;

else /* redefine using recursion */

result = n * factorial(n - 1);

return result;

}

int main()

{

printf( "%ld\n", factorial(6) );

return 0;

}

Tracing recursive programs

• Printing the input and output of each recursive call and

paying attention to the order of calls can give us an

insight on how recursion works! Let’s trace the factorial

problem:

long factorial(int n)

{

printf("computing %d!\n", n);

long result;

if (n == 0)

result = 1;

else

result = n * factorial(n - 1);

printf("returning result of %d!\n", n);

return result;

}

Tracing recursive programs

• Printing the input and output of each recursive call and

paying attention to the order of calls can give us an

insight on how recursion works! Let’s trace the factorial

problem:

long factorial(int n)

{

printf("computing %d!\n", n);

long result;

if (n == 0)

result = 1;

else

result = n * factorial(n - 1);

printf("returning result of %d!\n", n);

return result;

}

Tracing recursive programs

• Printing the input and output of each recursive call and

paying attention to the order of calls can give us an

insight on how recursion works! Let’s trace the factorial

problem:

long factorial(int n)

{

printf("computing %d!\n", n);

long result;

if (n == 0)

result = 1;

else

result = n * factorial(n - 1);

printf("returning result of %d!\n", n);

return result;

}

Does this remind you

of anything?

Tracing recursive programs

• C (and many other languages) use stacks for function

calls.

• When a new function is called its variables are pushed

on the variables of the caller function.

• When the function returns, all its variables are popped.

Push 6, push 5, push 4, push 3, push 2,

push 1, push 0.

Pop 0, pop 1, pop 2, pop3, pop 4, pop 5,

pop 6.

Does this remind you

of anything?

Yes, stacks

References

• J.R. Hanly & E.B. Koffman, Problem Solving and Program

Design in C (8thed.), Pearson, 2016

• Andy O’Fallon’s lecture notes for CptS121

(http://eecs.wsu.edu/~aofallon/cpts121)