I decided to grade each problem as follows 1 point for the description 2 points for performance derivation 1 point for correctly stating big O performance 1 point for correctly identifying what n is. Note, I described in class what I meant by high level description. This was somewhat fuzzy, but it was stated that it was NOT a line by line description of the routine.
int routineA(int base, int exponent){ int value = 1; int i; for(i=1;i<=exponent;i++) { value *=base; } return value; } This routine evaluates baseexponent Time = ∑i=1exponent 1 = 1+1+...+1 (n times) = n The algorithm is O(n) where n is the exponent.
int routineB(int base, int exponent) { if (exponent == 0) { return 1; } else { return base * routineB(base, exponent-1); } } This routine evaluates baseexponent T(0) = 1 T(n) = T(n-1) + c T(n-1) = T(n-1-1) + c = T(n-2)+c = T(n-2) + c + c = T(n-2) + 2c at step i T(n) = T(n-i) + ic let i = n T(n) = T(n-n) + nc = T(0) + nc = 1 + nc which is O(n) The algorithm is O(n) where n is the exponent. Notice: The best case and the worst case are the same for this algorithm. It is based on the exponent, the algorithm is O(n) if n is big or small.
double routineC(double coeffs[], int size, double x) { int i; double y=0; for(i=0;i<=size;i++) { y += coeffs[i] * pow(x,i); } } This routine will evaluate a polynomial P(x) = cnxn+cn-1xn-1...+c1x+c0 n in this case is the size of the array of coefficients, or the degree of the polynomial The inner loop evaluates the power function (see the two previous exercises) So the performance will be T = 0 + 1 + 2 + 3 + 4 + ... + n = ∑i=0n i = n(n+1)/2 Which is O(n2) This is a tricky problem, and easy to assume it is O(n). However, having just worked through the power function above, you should have seen this. Furthermore, question 5 refers you back to this problem, and gives a clue. you should have at least noted this as you read through the test the first time. The analysis of this problem is the same as the one we did for deleting an item from an arbitrary position in an array. I did fail to return a value here, but that does not change the performance of the algorithm.
void routineD(int ary1[], int ary2[], int size) {int i,j; for(i=0;i<size;i++) { ary2[j] = 1; for(j=0;j<5;j++) { ary2[i] *= ary1[i]; } } } This routine calculates n5 for each element in the first array and stores it in the second array. n is the size of the array. Notice the inner loop is constant. (Big but constant) So the performance is T = c + c + c + ... + c (n times) = ∑i=1nc = cn Which is O(n) This is exactly Stan's question during the review. I had an error on the 2nd line of the code, but again the performance did not depend on this error.
void routineE(int ary[], int size) { // findmin finds the position of the minimum element in the array // between (and including) the two endpoints passed) // this is an O(end-start) routine. int i, max; for(i=0;i<size-1;i++) { max = findmin(ary,i, size-1) swap(ary[max],ary[i]) } } This is selection sort. n is the size of the array. T(n) = n-1 + n-2 + n-3 + ... + 2 = ∑i=2n-1 i = n(n-1)/2 - 1 which is O(n2).
By dividing the problem into smaller parts, it is easier to solve the sub-parts.
divide the problem into sub-problems conquer, or solve the sub-problems combine, or reassemble the answer
Binary search. Check for an item at the middle of a sorted array If it is not there check the half of the array where the item would be.
bool binarySearch(array, element, start, stop)
- if (start > stop)
- return false
- mid = (start+stop)/2
- if array[mid] = element
- return true
- else if array[mid] < element
- return binarySearch(array, element, mid+1, stop)
- else
- return binarySearch(array, element, start, mid-1)
Line 3 is the divide step Lines 7 and 9 are the conquer steps The return in 7 and 9 are the combine
T(n) = T(n/2) + c T(n/2) = T(n/2/2) + c = T(n/22)+c T(n) = T(n/22) + c + c = T(n/22) + 2c at step i T(n) = T(n/2i) + ic assume n = 2k, lg(n) = k T(n) = T(n/sk) + kc = T(n/n) + kc = 1 + kc = 1 + c lg (n) which is O(lg(n)) Other answers are acceptable here, but why do anything more complex?
2 points An array is a collection of homogeneous objects characterized by constant time random access. 8 points Operations: change the value of an element O(1) extract the value of an element O(1) create the array O(1) destroy the array O(1) iterate over the array O(n) initialize the array to a set value O(n)
A compile time static array has memory allocated at compile time and the size is never changed. ex: int x[5]; A run time static array has memory allocated once during run time, and the size is never changed. ex: int * x; x = new int[size]; A dynamic array has memory allocated at run time, but this may be changed later in the program as memory is needed.
The C++ STL vector class is an implementation of a dynamic array. Elements may be added via the push_back routine. Elements may be deleted via the pop_back routine. Other normal array operations are supported.
Both of these operations may involve reallocating and copying data elements in the array. Assume in both cases, that memory is reallocated only when the array becomes full, and further assume that the amount of memory is doubled when this occurs. dupArray(array, size)This is an O(n) algorithm from line 2. Inserting at the end of a dynamic array will be a constant time operation as the item is inserted only at the end of the array, and no other data need be copied. push_back(array, e)
- tmp = new array twice the size of array
- for i=0, i<size, i++
- tmp[i] = array[i]
- delete array
- array = tmp
- maxsize = 2*size
Inserting into an arbitrary position will be at worst O(n) when we are inserting at the beginning of the array, as all data will need to be copied down one position. At best it will be constant, when the item is inserted at the end, and on average it will be T = 1/n * ∑i=0ni = 1/n * n(n+1)/2 = (n+1)/2 which is O(n) insert(array, e, pos)
- if size == maxsize
- dupArray(array, size)
- array[size] = e
- size ++
As we have seen in class, using dupArray will have O(1) performance in the average case.
- if size == maxsize
- dupArray(array, size)
- for i=size, i > pos, i++
- array[i] = array[i-1]
- array[pos] = e
Place a collection of elements in order.
Many answers are acceptable. Selection sort may not be used.
You should do this for 10 points extra credit on the test.
Given: P(x) = cnxn+cn-1xn-1...+c1x+c0
Horner's algorithm says:
P(x) = c0+x*(c1+x*(c2+x*( ...+x(cn-1+x*cn))...))