This preview has intentionally blurred sections. Sign up to view the full version.
View Full DocumentThis preview has intentionally blurred sections. Sign up to view the full version.
View Full DocumentThis preview has intentionally blurred sections. Sign up to view the full version.
View Full DocumentThis preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
Unformatted text preview: EE 312 Sp ’03 Exam 3 NAME: Section 1: Write recursive functions to solve each of the following four problems. Note that you
must write a recursive solution to receive any credit (a correct but nonrecursive solution will
receive zero points). You will receive AT MOST half credit if you use either a global variable or
a loop in your solution. For partial credit, describe (in English) what your base case (or base
cases, some of “the problems have more than one base case). Also describe how you are decomposing the problem to create a “smaller problem”. An explanation is not required (if your
program is correct you will receive full credit). 1 . (10 pts) Write a recursive function that calculates the number times the capital letter “X”
appears in a string. /* return the number of times “X” appears in string s */
int xes(char s) { } a. (for partial credit) What is (are) your base case(s) and what value is returned for each
base case? b. (for partial credit) How do you decompose the problem, i.e., what “smaller” problem (or
problems) do you solve by calling xes recursively? 2 . (10 pts) Write a recursive function to determine if x is a power of y. In other words, return
true if there exists an integer k such that x = Note that x cannot be a power of y unless x
is divisible by y.
/* return true if x is a power of y */
bool isPower (int x, int y) { a . (for partial credit) what is (are) your base case(s)? b . (for partial credit) what smaller problem(s) do you create in your decomposition step? 3 . (10 pts) Consider the following game played by two people. The game starts with n pennies
on the table. The two people take turns picking up pennies. Each turn, the player must either
pick up one penny, or the player can pick up “k” pennies (for some constant k). Whoever
picks up the last penny loses the game. For example, if “k” were 2 and we started with 5
pennies on the table, the game could go like this: player #1 picks up 1 penny (leaving 4
pennies on the table), player #2 picks up 2 pennies (leaving 2 pennies), player 1 picks up one
penny, and ﬁnally player 2 picks up the last penny and loses the game (i.e., player 1 wins). Note that, if k is 2, then player 1 should always win if the game starts with 5 pennies! The
reasoning is like this. Obviously, if there is only one penny left in the pile, whoever has to
take the next turn will lose. So, when n is 1, we are in a “losing state”. If there were two
pennies on the table, we could pick up 1 and then leave the other player in a losing state (just
one penny leﬁ). So, 2 pennies on the table is a winning state — whoever makes the next move
should always win. Similarly, (if k is 2) then 3 pennies is also a winning state (we could pick
up 2 pennies, leaving the other player in a losing state with just one penny left). So, 4
pennies must be a losing state since you must pick up either one penny or two pennies (when
k is 2) and hence you must leave your opponent with a winning state (either 11 = 2, or n = 3).
Since 4 is a losing state, then 5 must be a winning state. Write a recursive program that determines if “n” is a winning state (return true if n is a
winning state) for some value of k. Please note that k is an arbitrary constant — the value of k
cannot change during the game. / * return true if n pennies is a winning state for some constant k * /
bool winningState(int n, int k) { } for partial credit, explain your base case(s) and decomposition. 4. (10 pts) Consider the following mazelike game. We are given an array (named x) with n
integers. For example, the array could have the values { 0, 2, 1, 3, 2 }. We are also given a
“position”. The position is an index in the array, for example 4. Note that x[4] is the value 2.
Since the value in this position is 2, we can calculate our next position by either adding 2 or
subtracting 2 to our current position. Adding x[4] to 4 would give us the value 6, which is
outside the bounds of the array, so that move is illegal. So, our ﬁrst move would have to be
subtracting 2, and our next position is 2 (4 — 2 is 2). The value of x[2] is 1, so our next
position could either be 2 + l, or 2 — 1. Let’s assume we move to position 3 (2 + 1). The
value in this location is 3. From here, our only move is to position 0 and we win the game
(the object of the game is to get to position 0). Write a recursive program that determines if the game can be won in at most “m” more
moves. You Win the game if you can reach position 0. You lose the game if you cannot
make any more moves (and the position is something other than 0). Note that x[O] will
always have the value 0. Note that x[O] will be the only element in the array equal to 0. / * return true if there exists a sequence of no more than m moves to win the game
* x is the array telling you how far you can move (in either direction)
* n is the number of elements in the array
* pos is your current position in the array
* m is the number of moves you have left (until you lose)
*/ bool walk(int x , int n, int pos, int m) { 5 . (32 pts) Give an expression in “bigOh” notation for the amount of time the following
functions will take in the worst case a. (4 pts)
void doit(int x, int N) { for (int k = O; k < N; k += 1) {
for (j = 0; j < k; j += 1) {
X[k] = X[k] + X[j];
}
}
}
b. (4 pts) bool doit(int x, int N) {
for (int k = 1; k < N; k += 1) {
if (x[k] < x[k—1]) { return false; } } return true; } c. (4 pts)
void doit(int N) {
int k = 1;
while (k < N) {
k = k * 3;
k = k — l;
}
} d.(4 pts)
void doit(int N) {
int k = 0;
while (k < N) {
k = k + l;
} while (k > 0) {
k = k / 2;
}
} e. (4 pts)
/ * The following program implements a counter that counts in binary.
* each element of the array x is one bit in the counter, and we count up * until the most signiﬁcant bit is set */
void doit(int N) {
for (int k = 0; k < N; k += 1) { X[k] = O;
}
while (x[N—l] == 0) {
x[O] = l — x[O]; // flip bit 0
int k = 0;
while (k < N && x[k] == 0) { // ripple
k = k + l;
x[k] = 1 — x[k]; // flip bit k
}
}
}
f. (4 pts) int run(int N) {
if (N > 2) { return run(l) + run(N—l); }
else { return 0; } } g . (4 pts) Answer for the total time of doit (which depends on doneit).
int doit(int N) {
for (int k = o; k < N; k += 1) {
sum += doneit(N);
}
}
int doneit(int k) {
int j = 0;
while (j * j < k) {
j = j + l;
} return j; } h. (4 pts) What is the space complexity of this recursive function?
int splitUp(int x, int n) {
if (n < 2) { return x[O]; }
else {
int t1 = splitUp(&x[0], n / 3);
int t2 = splitUp(&x[n/3], n / 3);
int t3 = splitUp(&x[n/3 + n/3], n — 2*(n/3));
return t1 + t2 + t3; 6. (5 pts) How many times will the following function print out “oh boy”. Your answer must be
within 20% of the correct answer to receive credit. If it matters, you should assume the
program is run on a Windows computer and that the operating system has allocated one
megabyte of memory for stack space, and allocated 10 megabytes of memory for heap space. void duh(void) {
printf (“oh boy”) ;
duh() ; } 7. (5 pts) Emma Katherine is training for the Tour de France (she hopes to be the ﬁrst toddler to
ever wear the yellow jersey). Each evening, she pedals her tricycle in laps around the dining
room table. Meanwhile, her father clocks her lap times to the nearest 100th second and stores
the lap times on his computer using a C program. The lap times are stored in an array. We
are interested in calculating the average (mean) and minimum lap times for Emma. Should
we sort the array? Select the best choice among the following: (you should assume that N,
the number of elements in the array, is very large (if you had a toddler, you’d know this)). a. Yes, we should sort the array because after sorting the array, ﬁnding the minimum
element will be easy (the minimum will be at position 0 in the array after its been
sorted). Also, sorting will not affect the amount of time it takes to calculate the
average. b. Yes we should sort the array. But we need to ﬁnd the average ﬁrst, and then sort
the array (otherwise the program will be much slower). c. It does not matter if we sort the array or not. It will take O(N) time to ﬁnd the
average no matter what. If we sort the array, it will take 0(1) time to ﬁnd the
minimum but it will take O(N) time to sort the array (using the best case sorting
function). If we don’t sort the array, it will take O(N) time to ﬁnd the minimum.
Either way, the time is O(N) so it doesn’t matter. (1. We should not sort the array. Sorting takes too long and is too complicated for
such a simple problem. 8. (3 pts) How would your answer to question 7 change if we wanted to calculate the median
and the maximum time? Should we sort the array or not in that case? Recall that insertSort
takes O(N) time in the best case and O(NZ) in the worst and average cases. mergeSort takes
O(NlogN) time in all cases, and bubleSort always sucks. (answer SORT or DON’T SORT). 9. (5 pts) The following recursive program uses global variables WU CK). For which values of
N will the program calculate the correct value of the Fibonacci sequence. Recall that
Fibonacci for n = O, or n = 1 is 1, and for all subsequent values of n, Fibonacci(n) is equal to
the sum of the previous two values in the sequence. e.g., 1, 1, 2, 3, 5, 8, 13, 21, Give your answer as precisely as possible. If the program will not work for any values of N,
then say “never works”. If it works when N is smaller than 10, then say “it works for N
< 10”. If it works for N between 5 and 17 then say “works when 5 < N < 17”, etc. Draw
a box around your answer! Use the back of page 7 to show your work. int ans;
int temp_ans; void fib(int N) {
if (N < 2) { ans = 1; }
else {
fib(N1);
temp_ans = ans;
fib(N2);
ans = temp_ans + ans; 10. Multiple guess a. (2 pts) True or False: If we didn’t have recursion, then we wouldn’t need a stack
(we could get by without it). Because, if we didn’t have recursion, then the
amount of memory required for local variables and parameters would be 0(1),
and the compiler could statically allocate all the memory we would ever need for
activation records without using a stack. —— b. (3 pts) True or False The time complexity of a recursive function is never worse
than O(NlogN) _ c. (2 pts) Determining if an arbitrary number x is prime takes no more than 0(2”)
time in the worst case where n is the number of bits required to represent x. d. (3 pts) Multiple guess: I’ve been told that program A has time complexity of
O(Nz) and program B has time complexity of O(NlogN). Which of the following
most accurately describes programs A and B (circle exactly one choice). i. Program A will always be faster than program E
ii. Program B will always be faster than program A
iii. If I buy more memory, program A will run just as fast as program B
iv. Program B is almost certainly recursive, and Program A is not.
v. Program B will be faster than A for sufﬁciently large values of N, program
A may or may not be faster than program B for small values of N.
vi. If I get a fast computer, then I won’t care about the difference between
program A and program B. ...
View
Full Document
 Spring '08
 Shafer

Click to edit the document details