CS 1501 Fall 2001

Practice Questions for Midterm Exam

Here are some example questions that may help you to study for the midterm exam. Try to answer the questions fully before looking at the answers. Though these questions indicate some of the material that may be on the exam, they are by no means comprehensive. Remember to also study EVERYTHING up to the last class before the exam on the Syllabus and Class Schedule and the Algorithms Covered links, as well as everything pertaining to the first 3 assignments. 

Fill in the Blanks Complete the statements below with the MOST APPROPRIATE words/phrases.

a)      Two variations of QuickSort designed to minimize the probability of the worst case are __________________ and ___________________.

b)      The GradeSchool integer multiplication algorithm requires Theta______________ time for N-bit integers.

c)      If I have an open addressing hash table of size M, and a cluster of size C, the probability that a random key will be Inserted into the location immediately after the cluster is _________________.

d)      If I am using an RSA encryption scheme, I may DECRYPT my message first and have a receiver later ENCRYPT it for the purpose of having a ______________________________.

True/False Indicate whether each of the following statements is True or False.  For False answers, explain why it is false.

a)      If someone can discover an algorithm that factors integers in polynomial time, RSA will become useless as an encryption algorithm.

b)      The ShellSort algorithm has a worst-case run-time of Theta(N3/2) for an array of size N.

Short Answers and Calculations

1) You have two programs, Program A, which runs in time k1N and Program B, which runs in time k2log2(N) for some constants k1 and k2. Assume that for a problem of size No, both programs take X seconds to execute. Approximately how much time would each program take to run if we double the problem size? Show your work.

2) Define what it means to have a collision in a hash table, and why we cannot usually prevent them from occurring.

3) Consider InsertionSort of an array.  Explain what causes its worst case performance and derive the Theta run-time (in detail) of the algorithm in this case.

4) Consider the recursive pseudo-code function below:

void foo(int A[], int low, int high)

{

     if (low < high)

     {

         for (int i = low; i <= high; i++)

              constant_time_process(A[i]);

         for (int i = high; i >= low; i--)

              constant_time_process(A[i]);

         int mid = (low + high)/2;

         foo(A, low, mid);

         foo(A, mid, high);

         int index = randvalue(low, high);

         if (index < mid)

              foo(A, low, mid);

            

         else

              foo(A, mid, high);

     }

}

Give and justify the recurrence for this function, assuming that the original array size is N (from low to high). 

Coding

1) Assume that you have a C++ string of characters. Complete the function below that converts the string into a very long (ZZ) integer such that you can subsequently convert the integer back into a unique string if you so desire (in other words, each unique string should produce a unique ZZ).

 
void convert(char str[], ZZ& intval);
{
   // complete function body

 

2) Consider the code for QuickSort below:

 
void quicksort(itemType a[], int l, int r)
{ 
  int i, j; itemType v;
  if (r > l)
  {
     v = a[r]; i = l-1; j = r;
     for (;;)
     {
         while (a[++i] < v) ;
         while (a[--j] > v) ;
         if (i >= j) break;
         swap(a, i, j);
     } 
 
     swap(a, i, r);
     quicksort(a, l, i-1);
     quicksort(a, i+1, r); 
 } 
 
} 

Explain why the code as written will likely cause a run-time error, and correct it so that it will always run properly.  Be specific and give an example that will cause it to crash.


SOLUTIONS 

Fill in the Blanks Complete the statements below with the MOST APPROPRIATE words/phrases.

a)      Two variations of QuickSort designed to minimize the probability of the worst case are __median of three_ and __random pivot_____.

b)      The GradeSchool integer multiplication algorithm requires Theta____N2______ time for N-bit integers.

c)      If I have an open addressing hash table of size M, and a cluster of size C, the probability that a random key will be Inserted into the location immediately after the cluster is ___(C+1)/M_______.

d)      If I am using an RSA encryption scheme, I may DECRYPT my message first and have a receiver later ENCRYPT it for the purpose of having a _____digital signature________.

True/False Indicate whether each of the following statements is True or False.  For False answers, explain why it is false.

a)      If someone can discover an algorithm that factors integers in polynomial time, RSA will become useless as an encryption algorithm. TRUE

b)      The ShellSort algorithm has a worst-case run-time of Theta(N3/2) for an array of size N. FALSE.  We don't know precisely the lower bound on ShellSort, but we do know the upper bound (Big-O) is N3/2 if a good sequence for h is chosen.

Short Answers and Calculations

1) You have two programs, Program A, which runs in time k1N and Program B, which runs in time k2log2(N) for some constants k1 and k2. Assume that for a problem of size No, both programs take X seconds to execute. Approximately how much time would each program take to run if we double the problem size? Show your work.

For Program A, since the time is linear, we know that if we double the problem size the run-time should also double. Thus we can say 2X seconds for Program A. For Program B it is more complicated, since Program B runs in logarithmic time. However we can still solve this with some math:

We know: k2log2(No) = X

And we want to solve k2log2(2No) = ?

Remembering properties of logarithms, we can rewrite the problem as follows:

k2log2(2No) = k2[log2(2) + log2(No)] = k2 + k2log2(No) = k2 + X

2)  Define what it means to have a collision in a hash table, and why we cannot usually prevent them from occurring. 

A collision occurs in a hash table if, for two keys, x1 and x2, h(x1) = h(x2), with x1 != x2. Collisions cannot usually be prevented, since, in most instances, the key space being used (all possible keys) is greater in size than the table size, and, by the Pigeonhole Principle, at least two distinct keys must map to the same table location.

3) The worst case for InsertionSort of an array occurs when the data is initially reverse-sorted.  This produces the worst case because each item, when shifted from the "unsorted" (right) part of the array into the "sorted" (left) part of the array, must be moved all the way to the first location, resulting in the maximum amount of comparisons and shifts.  The Theta run-time in this case is derived as follows (assuming items start in location 1 of the array) for comparisons (the same analysis holds for shifts): 

For Item 2 we need 1 comparison to move it to location 1
For Item 3 we need 2 comparisons to move it to location 1
For Item 4 we need 3 comparisons to move it to location 1

For Item N we need (N-1) comparisons to move it to location 1

Summing the comparisons we get 1 + 2 + … + (N-1) which we know to equal (N-1)(N)/2, which is Theta(N2).

4) Given the initial array size of N, we see the following:  Each for loop will execute N times, requiring constant time for each iteration.  Thus, the for loops will require Theta(N) time.  There are 3 recursive calls that execute as a result of the first call, and each of those is on an array of half the original size.  Thus we get the overall recurrence  T(N) = 3T(N/2) + Theta(N).

Coding

1) Assume that you have a C++ string of characters. Complete the function below that converts the string into a very long (ZZ) integer such that you can subsequently convert the integer back into a unique string if you so desire.

 
void convert(char str[], ZZ& intval) // Your answers may vary
{
   int size = strlen(str);    // get length of string
   int curr;
   intval = 0;                // initialize integer to 0
   for (int i = size-1; i >= 0; i--) // starting at end of string to make conversion
                                     // back simpler
   {
        curr = str[i];        // get current character
        intval = (256 * intval) + curr;
                   // multiply by chosen radix and add current char value
                   // 256 is good if we are using the extended ASCII set   
   }
}

2) The loop while (a[--j] > v) ; may go past the left end of the array, since it does no bounds checking. For example, if the data in the array is initially reverse sorted, the pivot will be the smallest value in the array and the loop will not terminate within the bounds of the array. To fix this, we can either place a sentinel into location a[0] that is guaranteed to stop the loop, for ex: a[0] = 0; if all of the regular values are positive, or a[0] = v ; if the values can be anything. Alternatively, we could add another test to the loop:

while (j > l && a[--j] > v); // it is the variable l (for left) , not the number 1.