Introduction to Computer science - Programming Abstractions, Lecture 8, Lecture notes of Programming Abstractions

Slides for the couse of Programming Abstractions for Computer Science. Functional recursion

Typology: Lecture notes

2010/2011

Uploaded on 10/01/2011

hollyb
hollyb 🇺🇸

4.8

(44)

431 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Admin
Assign 2 due Wed
Today’s topics
Functional recursion
Reading
Reader ch. 4-5-6 (today-W-F)
Lec ture #8
Solving problems recursively
A recursive function calls itself — wacky!
Idea: solve problem using coworkers (clones) who
work and act like you
Delegate similar, smaller problem to clone
Combine result from clone(s) to solve total problem
Work toward trivial version that is directly solvable
For problems that exhibit "self-similarity"
Structure repeats within at different levels of scale
Solving larger problem means solving smaller problem(s) within
Feels mysterious at first
"Leap of faith" required
With practice, master the art of recursive decomposition
Eventually grok the underlying patterns
Functional recursion
Function that returns answer/result
Outer problem result uses result from smaller, same problem(s)
Base case
Simplest version of problem
Can be directly solved
Recursive case
Make call(s) to self to get results for smaller, simpler version(s)
Recursive calls must advance toward base case
Results of recursive calls combined to solve larger version
Power example
C++ has no exponentiation op
Iterative formulation for Raise function
baseexp = base * base * .... * base (exp times)
int Raise(int base, int exp)
{
int result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
pf3
pf4

Partial preview of the text

Download Introduction to Computer science - Programming Abstractions, Lecture 8 and more Lecture notes Programming Abstractions in PDF only on Docsity!

Admin

Assign 2 due Wed

Today’s topics

  • Functional recursion

Reading

  • Reader ch.^ 4-5-6 (today-W-F) Lecture # 8

Solving problems recursively

A recursive function calls itself — wacky!

Idea: solve problem using coworkers (clones) who

work and act like you

  • Delegate similar,^ smaller problem to clone
  • Combine result from clone(s) to solve total problem
  • Work toward trivial version that is directly solvable

For problems that exhibit "self-similarity"

  • Structure repeats within at different levels of scale
  • Solving larger problem means solving smaller problem(s) within

Feels mysterious at first

  • "Leap of faith" required
  • With practice, master the art of recursive decomposition
  • Eventually grok the underlying patterns

Functional recursion

Function that returns answer/result

  • Outer problem result uses result from smaller,^ same problem(s)

Base case

  • Simplest version of problem
  • Can be directly solved

Recursive case

  • Make call(s) to self to get results for smaller, simpler version(s)
  • Recursive calls must advance toward base case
  • Results of recursive calls combined to solve larger version

Power example

C++ has no exponentiation op

Iterative formulation for Raise function

  • baseexp =^ base * base * ....^ * base (exp times) int Raise(int base, int exp) { int result = 1; for (int i = 0; i < exp; i++) result *= base; return result; }

Recursive version

int Raise(int base, int exp) { if (exp == 0) return 1; else return base * Raise(base, exp-1); } } Base case } Recursive case

Now consider recursive formulation

  • baseexp^ =^ base^ *^ baseexp-

More efficient recursion

int Raise(int base, int exp) { if (exp == 0) return 1; else { int half = Raise(base, exp/2); if (exp % 2 == 0) return half * half; else return base * half * half; } }

baseexp^ = baseexp/2^ * baseexp/2^ (* base if exp is odd)

Avoid "arm's length" recursion

int Raise(int base, int exp) { if (exp == 0) return 1; else if (exp == 1) return base; else if (exp == 2) return base * base; else if (exp == 3) return base * base * base; else return base * Raise(base, exp - 1);

Aim for simple, clean base case

  • No need to anticipate other earlier stopping points
  • Avoid looking ahead before recursive calls,^ just let simple base case handle

Recursion and efficiency

Recursion provides no guarantee of (in)efficiency

  • Recursion can require same resources as alternative approach
    • Or recursion may be much more or much less efficient
  • For problems with simple iterative solution, iteration is likely the best

Why recursion then?

  • Can express with clear, direct, elegant code
  • Can intuitively model a task that is recursive in nature
  • Solution may require recursion —!iteration won't do!

Choose code

int C(int n, int k) { if (k == 0 || k == n) return 1; else return C(n-1, k) + C(n-1, k-1); }

Simplest base case

  • when^ no^ choices remain at all