CS100A Lecture 25 1 December...

advertisement
CS100A Lecture 25 1 December 1998
Chance to replace grade on Prelim 3, Question 2.
Everyone is expected to be in lecture on Thursday, 3
December. A short quiz concerning the development of
a loop from a invariant will be given --you will have to
develop a loop with initialization given the invariant.
We will raise your grade on Question 2 of Prelim 3 to
your grade on this quiz (but we won’t lower anyone’s
grade on Prelim 3) IF:
• (0) Your grade on the quiz is larger than your grade on
Question 2 of Prelim3 and
• (1) You turn in your Prelim3 with the Quiz.
Also, we will hand out course evaluations for you to
complete and hand in at the end of the lecture.
CS100A, Lecture 25, 1
December 1998
1
Memorize this slide
A loop invariant is a true-false statement about the variables used in a loop that is true before and after each
iteration.
Given an invariant P, we can develop a loop with
initialization in four steps:
• (1) Create initialization that makes P true.
• (2) Determine the condition B so that from !B and P you
can see that the desired result is true. (Or, equivalently,
determine the condition B such that you know the desired
result is not true.)
• (3) Figure out what statement(s) to put in the loop body
to make progress toward termination of the loop.
• (4) Figure out what else the loop body should do to ensure that after execution of the loop body invariant P is
still true.
init;
// invariant P: …
S must make progress
while ( B )
and keep P true
{S}
CS100A, Lecture 25, 1
December 1998
2
Recursion
A method is recursive if it calls itself. Many algorithms
are most easily written using recursive methods.
To see that recursive method calls (calls of a method
from within the body of a method) work, you have only
to execute a method call of a recursive method yourself,
using the rules that you already know. We’ll show that
for a simple case in this lecture.
However, to understand that a particular recursive
method is correct, you should not think about executing
it. Rather, do two things:
•(0) Understand that each recursive method call is correct
in terms of the specification of the method.
•(2) Make sure that the recursion “terminates” (much like
making sure that a loop terminates). That is, see to it that
in some sense the arguments of the recursive call are
“smaller” than the parameters of the method and that
when the parameters are “as small as possible”, the
method terminates without calling itself recursively.
We’ll see this in the examples.
CS100A, Lecture 25, 1
December 1998
3
Return the reverse of a string
// Return the reverse of string s. For example, if s is
// “abcd”, return the string “dcba”.
public static String rev(String s) {
// If the string is empty or contains one character,
return it
if (s.length( ) <= 1) return s;
// The string has the form C c, where C is a character;
// c is a string. C is s.charAt(0). c is s.substring(1).
// Return the reverse of c catenated with C
return rev(s.substring(1)) + charAt(0);
}
Note that the argument to the recursive call
rev(s.substring(1))
has one less character than parameter s. Therefore, the
“depth” of recursion --the maximum number of recursive
calls with frames that will exist at any time-- is the
number of characters in s.
CS100A, Lecture 25, 1
December 1998
4
Execution of rev
// Return the reverse of string s.
public static String rev(String s) {
if (s.length( ) <= 1) return s;
return rev(/*L2:*/s.substring(1)) + charAt(0);
}
------------------ in main method:--------------String t= /*L1:*/ rev(“abc”);
M0: frame for main.
Called from system
t ____
F0: first frame for rev.
Called from main.L1, frame M0
s “abc”
F2: second frame for rev.
Called from rev.L2, frame F1
s “bc”
F3: third frame for rev.
Called from rev.L2, frame F2
s “c”
CS100A, Lecture 25, 1
December 1998
5
Method to remove blanks
// Return a copy of s, but with blanks removed
public static String removeBlanks (String s) {
if (s.length() = 0) return s;
if (s.charAt(0) = ‘ ‘) return s.substring(1);
// first character of s is not a blank.
// Return first character followed by rest of s
// but with blanks removed
return s.charAt(0) + removeBlanks(s.substring(1));
}
Method to duplicate each character
// Return a copy of s but with each character repeated
public static String dup(String s) {
if s.length() == 0) return s;
return s.charAt(0) + s.charAt(0) +
dup(s.substring(1));
}
CS100A, Lecture 25, 1
December 1998
6
Recursive method to lower-case a String
// Return a copy of s with all capital letters lower-cased
public static lowerCase(String s) {
if (s.length()= 0) return s;
// Store into c the first character, lower-cased
// if necessary
char c= s.charAt(0);
if (‘A’ <=s.charAt(0) && s.charAt(0) <=‘Z’)
c= (char) ((int)s.charAt(0) -26);
return c + lowerCase(s.substring(1));
}
Recursive method for logarithmic exponentiation
// Given b>= 0, return ab
public static int exp(int a, int b) {
if (b == 0) return 1;
if (b is odd) return a * exp ( b-1);
// b is even, so ab = (a*a)b/2
return exp(a*a, b/2);
}
CS100A, Lecture 25, 1
December 1998
7
Tiling a kitchen with L-shaped squares
Our house has a kitchen which is 2n x 2n feet square (for
some integer n). A small, 1 x 1 refrigerator sits on one
square of the room. How can we tile the floor with Lshaped tiles that look like this (2 x 2 feet with a 1 x 1
section missing)?
2n
Kitchen, showing two
possible locations for
the refrigerator
2n
CS100A, Lecture 25, 1
December 1998
8
// Given n >= 0 and a 2n x 2n feet square room with one
// square filled, tile room with L-shaped squares (see
// previous slide)
public static tile(Floor p, int n) {
if (n=0) return;
Draw horizontal and vertical lines in middle of room
p, as shown to the
right. One of the
four quadrants has a
2n-1
a 1 x 1 square filled
.
(example shown).
Place an L-shaped
tile as shown to the
2n-1
right, so that each
of the other quad2n-1
rants has a square
2n-1
filled. Now call
tile(p1,n-1) four times, where each time p1 is one
of the four quadrants, to tile the four quadrants.
}
CS100A, Lecture 25, 1
December 1998
9
// Given n>=0, return !n = 1*2*3*…*n
public static factorial(int n) {
if (n<=1) return 1;
return n * factorial(n-1);
}
// Binary search --Given is b[0..h] <= x < b[k..n-1] and
// h < k and b is sorted (in ascending order).
// Return an integer j satisfying b[0..j] <= x < b[j+1].
Public static bsearch(int[ ] b, int h, int k) {
if (h+1 = k) return h;
int e= (h+k)/2;
if (b[e] <= x)
return bsearch(b, e, k);
else return bsearch(b, h, e);
}
CS100A, Lecture 25, 1
December 1998
10
Fibonacci numbers Fn given by:
F0 = 0
F1 = 1
Fn = Fn-1 + f n-2 for n>1
// Given n>= 0, return Fn --inefficient version
public static fib(int n) {
if (n<=1) return n;
return fib(n-1) + fib(n-2);
}
-----------------------------------------------------------------------// Given n>= 0, return Fn --efficient version
public static fibe(int n) {
if (n=0) return n;
return fibh(n,0,1,1)
}
// Given: 0<m<=n and Fm-1 = a and Fm=b, return Fn
public static fibh(int n, int a, int b, int m) {
if (m=n) return b;
return fibh(n, b, a+b, m+1);
}
CS100A, Lecture 25, 1
December 1998
11
Download