Midterm Test Solutions for CS61B, Fall 2007: Algorithm Analysis and Complexity, Exams of Data Structures and Algorithms

The solutions to the midterm test of the cs61b course at the university of california, berkeley, taught by p. N. Hilfinger in fall 2007. The test covers topics such as checking if a number is less than 0 using bitwise operators, function to determine if there is an odd number of 1-bits in an integer, and asymptotic analysis of algorithms.

Typology: Exams

2012/2013

Uploaded on 04/02/2013

shashi_16star
shashi_16star 🇮🇳

4.6

(20)

99 documents

1 / 10

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
DO NOT
REPRODUCE
CS61B, Fall 2007 Midterm Test Solutions P. N. Hilfinger
1. [10 points]
a. How can you check to see if a number is less than 0 using only == and the bit operators (&,
|,^,~,<<,>>,>>>)?
There are many possible answers. Here are a few:
(x>>>31) == 1
(x & 0x7fffffff) != x
(x & 0x80000000) != 0
(x << 1 >>> 1) != x
b. The following program compiles correctly. What does the main program (in D) print?
class A {
int z = 2;
void f () { this.g (); }
void g () { System.out.printf ("A:%d%n", z); }
int h () { return z; }
}
class B extends A {
int z = 15;
void g () { System.out.printf ("h:%d z:%d%n", h(), z); }
}
class C extends A {
int z = 42;
void f () { this.g (); }
}
class D {
public static void main (String[] args) {
A c1 = new C();
C c2 = new C();
A b1 = new B();
B b2 = new B();
c1.f ();
c2.f ();
b1.f ();
b2.f ();
}
}
Answer:
A:2
A:2
h:2 z:15
h:2 z:15
1
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Midterm Test Solutions for CS61B, Fall 2007: Algorithm Analysis and Complexity and more Exams Data Structures and Algorithms in PDF only on Docsity!

DO

NOT

REPRODUCE

CS61B, Fall 2007 Midterm Test Solutions P. N. Hilfinger

  1. [10 points]

a. How can you check to see if a number is less than 0 using only == and the bit operators (&, |, ^, ~, <<, >>,>>>)? There are many possible answers. Here are a few: (x>>>31) == 1 (x & 0x7fffffff) != x (x & 0x80000000) != 0 (x << 1 >>> 1) != x

b. The following program compiles correctly. What does the main program (in D) print?

class A { int z = 2; void f () { this.g (); } void g () { System.out.printf ("A:%d%n", z); } int h () { return z; } }

class B extends A { int z = 15; void g () { System.out.printf ("h:%d z:%d%n", h(), z); } }

class C extends A { int z = 42; void f () { this.g (); } }

class D { public static void main (String[] args) { A c1 = new C(); C c2 = new C(); A b1 = new B(); B b2 = new B(); c1.f (); c2.f (); b1.f (); b2.f (); } } Answer: A: A: h:2 z: h:2 z:

DO

NOT

REPRODUCE

c. Succinctly describe the result of calling the following function:

int p (int x) { int n; n = 0; while (x != 0) { n = n ^ x; x = x >>> 1; } return n & 1; } Returns 1 iff there are an odd number of 1 bits in x, and 0 otherwise.

d. In the function for part (c) above, how would the result differ if we replaced >>> with >>?

You’d get an infinite loop if x is negative.

e. What is the result of compiling and executing the following? Briefly explain your answer.

abstract class A { abstract void f (); }

class B { void f () { printf ("Hello, world!"); } }

public class Main { public static void main (String[] args) { Object b = new B(); g ((A) b); }

static void g (A x) { x.f (); } } The cast (A) b causes a run-time exception, because the type of b is not a subtype of A, even though it implements exactly the same methods.

DO

NOT

REPRODUCE

d. The running time, as some function of low and high, for search, declared below. That is, define a suitable function s(low, high), and then give a bound for Csearch(N ), in terms of N , where N = s(low, high). (E.g., “Cost of search(N ) = O(N 2 ), where N = lg(high + low)”). (Again, I’m asking for upper and lower bounds on the time, not just a bound on the worst- case time).

bool search (int A[], int value, int low, int high) { if(high < low) return false; int mid = (low + high) / 2; if (A[mid] > value) return search(A, value, low, mid - 1); else if (A[mid] < value) return search(A, value, mid + 1, high); return true; }

Worst-case: O(lg N ), where N = (high) − (low). Best-case: Ω(1) here.

e. The running time (not just worst-case), as a function of n, for G(n), for G declared

void G(int n) { if (n == 1) return; for(int i = 0; i < n; i += 1) G(n-1); } Answer: Θ(n!).

DO

NOT

REPRODUCE

  1. [1 point] What is an example of preadaptation?

This (rather ill-chosen) term refers to the evolution of inherited features to serve purposes much different from their originals. A classic example is that extra gill arches in ancient fish evolved to become jaw bones.

  1. [10 points] Using the following class definitions:

class IntList { // ’final’ means head can’t be changed after the constructor // sets it. public final int head; public IntList tail; public IntList (int head, IntList tail) { this.head = head; this.tail = tail; } }

class IntList2 { public final IntList head; public IntList2 tail; public IntList2 (IntList head, IntList2 tail) { this.head = head; this.tail = tail; } }

fill in the methods below and on the next page to agree with their comments. Define any additional methods you’d like. HINT: don’t try to make things efficient. You’ll probably find it easier to create one list at a time.

DO

NOT

REPRODUCE

/* b. / /* A list of N lists such that list #k contains all the items in L

  • that are equal to k modulo N, in their original order. For
  • example, if N is 3 and L contains [9, 2, 7, 12, 8, 1, 6],
  • then the result is [ [9, 12, 6], [7, 1], [2, 8] ]. The operation
  • is nondestructive (the original contents of L are not changed). */ static IntList2 slice (IntList L, int N) { return slice (L, N, 0); }

static IntList2 slice (IntList L, int N, int k) { if (k >= N) return null; else return new IntList2 (select (L, N, k), slice (L, N, k+1)); }

static IntList select (IntList L, int N, int k) { if (L == null) return null; else if (L.head % N == k) return new IntList (L.head, select (L.tail, N, k)); else return select (L.tail, N, k); }

DO

NOT

REPRODUCE

Alternative solution to part (a):

/* a. / /* Slice the list L into a list of N lists such that list #k contains

  • all the items in L that are equal to k modulo N, in their original
  • order. For example, if N is 3 and L contains [9, 2, 7, 12, 8, 1, 6],
  • then the result is [ [9, 12, 6], [7, 1], [2, 8] ]. The operation
  • is destructive (it may destroy the original list) and creates no new
  • IntList objects (it will, of course, create new IntList2 objects). */ static IntList2 dslice (IntList L, int N) { IntList2 result;

result = null; for (int k = N-1; k >= 0; k -= 1) { result = new IntList2 (first (L, k, N, true), result); IntList next = first (L, k, N, false); separate (L, k, N); } return result; }

static IntList first (IntList L, int k, int N, boolean wantEqual) { while (L != null && (L.head % N == k) == wantEqual) L = L.tail; return L; }

static void separate (IntList L, int k, int N) { IntList lastK, lastNotK; lastK = lastNotK = null; while (L != null) { IntList next = L.tail; if (L.head % N == k && lastK == null) lastK = L; else if (L.head % N == k) lastK = lastK.tail = L; else if (lastNotK == null) lastNotK = L; else lastNotK = lastNotK.tail = L; L.tail = null; L = next; } }

DO

NOT

REPRODUCE

public Iterator iterator () { return new FilterIterator (); }

private class FilterIterator implements Iterator { private int n, lim; FilterIterator () { n = 0; lim = size (); } public boolean hasNext () { return n < lim; } public T next () { n += 1; return get (n-1); } } }

b. Here is a second formulation of the slice problem from above. Fill it in, using the FilteredList abstraction from part (a) above. We suggest that the returned value be an ArrayList<List>.

/** A list of N lists such that list #k contains all the items in L

  • that are equal to k modulo N, in their original order. For
  • example, if N is 3 and L contains [9, 2, 7, 12, 8, 1, 6],
  • then the result is [ [9, 12, 6], [7, 1], [2, 8] ]. The operation
  • is nondestructive (the original contents of L are not changed). */ static List<List> slice (List L, int N) { ArrayList<List> result = new ArrayList<List> (); for (int k = 0; k < N; k += 1) result.add (new FilteredList (L, new ModFilter (k, N))); return result; }

class ModFilter implements Predicate { int k, N; ModFilter (int k, int N) { this.k = k; this.N = N; } public boolean test (Integer x) { return x % N == k; } }