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