dis4

dis4 - CS32 Discussion  Sec.on 1B  Week 5 ...

This preview shows page 1. Sign up to view the full content.

This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: CS32 Discussion  Sec.on 1B  Week 5  TA: Brian Choi  Reminder  •  Homework 3  –  Due Sunday  •  Midterm  –  5/5 Wednesday  –  Open book, open notes, closed friends.  Recursion  •  Func.on‐wri.ng technique where the func.on refers to itself.  •  Recall the following func.on:  int factorial(int n) { if (n == 0) return 1; return n * factorial(n – 1); } •  Let us talk about how to come up with such a func.on.  Decomposi.on of the problem  •  You’re all used to the following technique.  int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n! = 1 * 2 * 3 * … * (n‐1) * n  Decomposi.on of the problem  •  You’re all used to the following technique.  int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n! = 1 * 2 * 3 * … * (n‐1) * n                 = (n‐1)!  Decomposi.on of the problem  •  You’re all used to the following technique.  int factorial(int n) { int temp = 1; for (int i = 1; i <= n; i++) temp *= i; return temp; } •  n! = 1 * 2 * 3 * … * (n‐1) * n    •  n! = factorial(n‐1) * n  Decomposi.on of the problem  int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  n! = 1 * 2 * 3 * … * (n‐1) * n    •  n! = factorial(n‐1) * n  Power of Belief  •  JUST BELIEVE factorial(n ‐ 1) will do the right thing.  int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  •  •  •  factorial(n) will believe that factorial(n‐1) will return the right value.  factorial(n‐1) will believe that factorial(n‐2) will return the right value.  …  factorial(1) will believe that factorial(0) will return the right value.   Power of Belief  •  JUST BELIEVE factorial(n ‐ 1) will do the right thing.  int factorial(int n) { int temp = factorial(n - 1) * n; return temp; } •  •  •  •  •  factorial(n) will believe that factorial(n‐1) will return the right value.  factorial(n‐1) will believe that factorial(n‐2) will return the right value.  …  factorial(1) will believe that factorial(0) will return the right value.  AND MAKE factorial(0) return the right value!   Base Case  •  JUST BELIEVE factorial(n ‐ 1) will do the right thing.  int factorial(int n) { if (n == 0) return 1; int temp = factorial(n - 1) * n; return temp; } •  •  •  •  •  factorial(n) will believe that factorial(n‐1) will return the right value.  factorial(n‐1) will believe that factorial(n‐2) will return the right value.  …  factorial(1) will believe that factorial(0) will return the right value.  AND MAKE factorial(0) return the right value!   Base Case  •     int factorial(int n) { if (n == 0) return 1; int temp = factorial(n - 1) * n; return temp; } Pa^ern  •  How to Write a Recursive Func.on for Dummies (no oﬀense!)  1.  Find the base case.  –  –  When should the recursion stop?  What is the last brick?  2.  Decompose the problem.  –  The simplest case  •  Run the same func.on on n‐1 items.  •  What informa.on do I get out of it?  •  How do I use this informa.on to say something about n items?  3.  Justsolve this subproblem!  Pa^ern  •  Once you have answered all the ques.ons. Write them out  this way:  •  func.on_header   {     take care of the base cases     write the rela.onship between the prev step and the curr step   }  •  Lastly, look back and make sure every call to this func.on hits  some base case eventually.  Prac.ce 1: Average  double average(const double arr, int n) { // assume n > 0 } Prac.ce 1: Average  •  What is the base case?  •  What is the rela.onship between (n)‐step and (n‐1)‐step?  That is, how do I get the average of n items, knowing the  average of n‐1 of them?  Prac.ce 1: Average  •  •  What is the base case?  n = 1, where the average is just the value of the only item.  What is the rela.onship between (n)‐step and (n‐1)‐step?  That is, how do I get the average of n items, knowing the  average of n‐1 of them?  •  average(arr, n)   = total(all n items) / n       = {total(ﬁrst n‐1 items) + n‐th item} / n            = average(arr, n‐1) * (n‐1) + n‐th item                   n  •  Prac.ce 1: Average  double average(const double arr, int n) { if (n == 1) return arr[0]; double prevTotal = (n – 1) * average(arr, n – 1); return (arr[n – 1] + prevTotal) / n; } Prac.ce 2: Summing Digits  int sumOfDigits(const int n) { // assume n >= 0 } Prac.ce 2: Summing Digits  •  What is the base case?  •  What is the rela.onship between (n)‐step and (n‐1)‐step?  That is, how do I get the sum of n digits, knowing the sum of  digits of (n‐1) digits?  Prac.ce 2: Summing Digits  •  •  What is the base case?  n < 10 (i.e., n is a single digit number), where the sum of  digits is simply n  •  What is the rela.onship between (n)‐step and (n‐1)‐step?  That is, how do I get the sum of n digits, knowing the sum of  digits of (n‐1) digits?  Just add the last digit to the sum!  •  Prac.ce 2: Summing Digits  int sumOfDigits(const int n) { if (n < 10) return n; return n % 10 + sumOfDigits(n / 10); } Prac.ce 3: Dele.ng characters  string deleteChar(const string s, const char c) { } Prac.ce 3: Dele.ng characters  •  What is the base case?  •  What is the rela.onship between (n)‐step and (n‐1)‐step?   Prac.ce 3: Dele.ng characters  •  •  What is the base case?  s == “”: There is no character to delete! Just return “”.  •  •  What is the rela.onship between (n)‐step and (n‐1)‐step?   Suppose the string is of length n, and I make a recursive call  on s.substr(1). (e.g. If the string is “hello”, the recursive call  will be made on “ello”.)  What’s returned by deleteChar must not contain any c. You  only need to append s[0] to it if s[0] != c. If s[0] == c, just  return it.  •  Prac.ce 3: Dele.ng characters  string deleteChar(const string s, const char c) { if (s == “”) return “”; if (s[0] == c) return deleteChar(s.substr(1), c); else return s[0] + deleteChar(s.substr(1), c); } Prac.ce 4: Fibonacci numbers  •  Fibonacci numbers refer to the sequence of numbers of the  following form:  0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …  –  –  –  F(0) = 0  F(1) = 1  F(n) = F(n‐1) + F(n‐2), n >= 2  Prac.ce 4: Fibonacci numbers  // A little too obvious now, isn’t it? int fibo(const int n) { if (n == 0) return 0; if (n == 1) return 1; return fibo(n – 1) + fibo(n – 2); } Prac.ce 4: Fibonacci numbers  •  Note that ﬁbo() makes two recursive calls.     ﬁbo(4)  ﬁbo(3)  ﬁbo(2)  ﬁbo(1)  •  ﬁbo(1)  ﬁbo(0)  Look at all this redundancy!!!!  ﬁbo(2)  ﬁbo(1)  ﬁbo(0)  Trick: Memoiza.on  int fibMem[100]; // global for (int i = 2; i < 100; ++i) fibMem[i] = -1; fibMem[0] = 0; fibMem[1] = 1; if (fibMem[n-2] != -1) fib2 = fibMem[n-2]; else fib2 = fibo(n-2); fibMem[n] = fib1 + fib2; int fibo(const int n) { int fib1, fib2; if (fibMem[n-1] != -1) fib1 = fibMem[n-1]; else fib1 = fibo(n-1); return fib1 + fib2; } Memoiza.on is an op.miza.on technique that  basically helps avoid compu.ng the same value  over and over by remembering it.  We like this since memory is cheap, but  compu.ng .me is not!  Prac.ce 5: Palindrome  •  Examples: “eye”, “racecar”, “deed”  bool palindrome(const string s) { } •  •  Base case? (Hint: An empty string is a palindrome.)  General case?  Prac.ce 5: Palindrome  •  Examples: “eye”, “racecar”, “deed”  bool palindrome(const string s) { }  •  Cases: (1) size = 0, (2) size = 1, (3) the ﬁrst char diﬀers from  the last one, (4) ﬁrst char = last char  Prac.ce 5: Palindrome  •  Examples: “eye”, “racecar”, “deed”  bool palindrome(const string s) { if (s.size() == 0 || s.size() == 1) return true; if (s[0] != s[s.size() - 1]) return false; return palindrome(s.substr(1, s.size() - 2)); }  •  Cases: (1) size = 0, (2) size = 1, (3) the ﬁrst char diﬀers from  the last one, (4) ﬁrst char = last char  Prac.ce 6: targetSum  •  Given a set of integers, can we ﬁnd a combina.on that sums  up to exactly targetSum?  bool targetSum(int a, int n, int targetSum) { } •  •  Base case?  General case?  Prac.ce 6: targetSum  •  Given a set of integers {1, 2, 3}, can we ﬁnd a combina.on  that sums up to exactly targetSum?  bool targetSum(int a, int n, int targetSum) { } •  •  Base case? If n == 0, no such sum exists. If the current  number is exactly targetSum, then that’s it.   General case? Either the current number is part of the  targetSum, or is not included in the targetSum.  Prac.ce 6: targetSum  •  Given a set of integers {1, 2, 3}, can we ﬁnd a combina.on  that sums up to exactly targetSum?  bool targetSum(int a, int n, int targetSum) { if (n == 0) return false; if (*a == targetSum) return true; return exactSum(a + 1, n – 1, targetSum - *a) || exactSum(a + 1, n – 1, targetSum); } Prac.ce helps  •  •  •  Recursion is somewhat counter‐intui.ve when confronted for  the ﬁrst .me.  Just do a lot of prac.ce and you will see the pa^ern.  Again, the key to recursion is to “believe”! Do not try to track  the call stack down and see what happens un.l you really  have to.  Test Taking Tips  •  •  •  •  I know it’s open book, but osen it helps to create cheat  sheets anyways.  Have some “representa.ve” example codes available in your  notes.  But do not try to copy from hw/proj solu.ons! We have seen  so many people using variable names and func.on calls from  projects, when they don’t even exist in the exam ques.ons!  (e.g., using Animal class’s name() func.on when the problem  asks you to build a class called Tank.)  Get a lot of sleep before coming into the exam site.   ...
View Full Document

This note was uploaded on 02/09/2012 for the course CS 32 taught by Professor Davidsmallberg during the Spring '08 term at UCLA.

Ask a homework question - tutors are online