CS 46B - Lecture 8
Pre-class reading
Fibonacci Sequence
- Fibonacci sequence is a sequence of numbers defined by
f1 = 1
f2 = 1
fn = fn-1 + fn-2
- First ten terms:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
The Efficiency of Recursion
- Recursive implementation of fib is straightforward
- Watch the output closely as you run the test program
- First few calls to fib are quite fast
- For larger values, the program pauses an amazingly long time between outputs
- To find out the problem, insert trace messages (see lab)
Call Tree for Computing fib(6)
The Efficiency of Recursion
The Efficiency of Recursion
- Occasionally, a recursive solution runs much slower than its iterative counterpart
- In most cases, the recursive solution is only slightly slower
- The iterative isPalindrome performs only slightly better than recursive solution
- Each recursive method call takes a certain amount of processor time
- Smart compilers can avoid recursive method calls if they follow simple patterns
- Most Java compilers don't do that
- In many cases, a recursive solution is easier to understand and implement correctly than an iterative solution
To iterate is human, to recurse divine.
, L. Peter Deutsch
Iterative isPalindrome Method
public boolean isPalindrome()
{
int start = 0;
int end = text.length() - 1;
while (start < end)
{
char first = Character.toLowerCase(text.charAt(start));
char last = Character.toLowerCase(text.charAt(end));
if (Character.isLetter(first) && Character.isLetter(last))
{
// Both are letters.
if (first == last)
{
start++;
end--;
}
else
{
return false;
}
}
if (!Character.isLetter(last)) { end--; }
if (!Character.isLetter(first)) { start++; }
}
return true;
}
Lecture 8 Clicker Question 1
Consider the triangle number computation in the Triangle.getArea method.
- The recursive method is faster than a loop that computes 1 + 2 + 3 + . . . + width
- A loop is a little bit faster than the recursive method
- A loop is a lot faster than the recursive method
- Who cares? It is much faster to compute width * (width + 1) / 2.
Permutations
To Generate All Permutations
- Generate all permutations that start with 'e' , then 'a', then 't'
- To generate permutations starting with 'e', we need to find all permutations of "at"
- This is the same problem with simpler inputs
- Use recursion
To Generate All Permutations
- Loop through all positions in the word to be permuted
for (int i = 0; i < word.length(); i++)
- For each position, compute the shorter word obtained by removing i-th letter:
String shorter = word.substring(0, i) + word.substring(i + 1);
- Get permutations of the shorter word:
ArrayList<String> shorterPermutations = permutations(shorter)
To Generate All Permutations
Lecture 8 Clicker Question 2
What are all permutations of the four-letter word beat?
- beat, eatb, atbe, tbea
- beat, beta, baet, bate, btea, btae
- beat, beta, baet, bate, btea, btae, eatb, etab, aetb, ateb, teab, taeb
- b followed by the six permutations of eat, e followed by the six permutations of bat, a followed by the six permutations of bet, and t followed by the six permutations of bea
Lecture 8 Clicker Question 3
Permutations, shmermutations. Let's talk about subsequences instead. In a subsequence, you don't use all the letters, but you must use them in the same order in which they appear in the original. For example, "brat" -> [, a, at, b, ba, bat, br, bra, brat, brt, bt, r, ra, rat, rt, t]
If the word has n letters, how many subsequences are there?
- n
- n!
- n2
- 2n
Lecture 8 Clicker Question 4
Now we are supposed to find all subsequences of the word turn. And let's say that by good fortune we already know all subsequences of the word urn.
What do we do?
- For each of the subsequences of
urn, put t in front
- For each of the subsequences of
urn, put t in all possible positions. For example, if we have un, produce tun, utn, and unt.
- For each of the subsequences of
urn, either put t in front or don't.
- That's no good. We also need the subsequences of
tur, tun, and trn.
Lecture 8 Clicker Question 5
We now have some pseudocode:
subsequences(word)
result = empty list
first = first character in word
subs = subsequences(word without the first character)
for each s in subs
add first + s and s to result
return result
But we still need a base case so that the recursion can come to an end.
What is the minimal base case that we can use?
- If word has only one character, return a list containing word
- If word has only one character, return a list containing word and the empty string
- If word is empty , return an empty list
- If word is empty , return a list containing the empty string
Lecture 8 Clicker Question 6
Now it's your turn. Code it up here.
What do you get for subsequence #148?
- San Jos
- SaJé
- anoé
- Something else