Notes... In this file ^ is used for exponentiation and _ is used for sub-script. So, n^2 is what I use for "n squared". And log_2(n) is what I use for "log base 2 of n". Note that these symbols (^ and _) do not have that meaning in a C/C++ program, so don't do that. 1. Convert 7 in decimal to binary. Answer: To convert from decimal to binary, you can either do "guess and check" for a number this small or use an algorithm. To do guess and check, you guess and make sure it's right. For example, guess 110 is the answer; convert that to binary and you get 6, so that's not right, then try 111, and find out that is correct. The easiest algorithm to use is... * if number is odd, write a 1 down, else write a 0 down. * divide the number by 2 (rounding down) and repeat, writing numbers down to the left of ones already written down. For 7, this proceeds like... * 7 is odd, so write a 1. * Divide 7 by 2, now we have 3. * 3 is odd, add a 1 to the front of the 1 we have alrady, so we have 11. * Divide 3 by 2, now we have 1. * 1 is odd, add a 1 to the front of the 11 we have laready, so we have 111. * Divide 1 by 2, now we have 0, and we're done. 111 is the answer. Convert 1100 0110 to binary. Show your work. What character does this represent in ASCII? Answer: The powers of two for the bits are 128, 64, 32, 16, 8, 4, 2, 1. So the number is 128+64+4+2 = 198. That is not a letter in the ASCII table because it's not between 65-90 or between 97-122. So the right answer would be something like "198 and not a letter". 2. What is the range of values that can be stored in a 10 bit unsigned integer? Answer: from 0000000000 to 1111111111. If you convert those to decimal, you get that the range is from 0 to 1+2+4+8+16+32+64+128+256+512 = 1023. Or, use the formula 2^10 - 1, which also gives 1023. Give the binary representation of the largest 10 bit unsigned integer. Answer: 1111111111 Give the formula for the largest unsigned integer that uses 1 million bits. Answer: The formula is 2^(#bits) - 1. So, 2^(1000000) - 1. 3. Fill in the table of big-O running times, where n is the # of numbers. Algorithm Running time ------------------------------------------------- Linear search O(n) Binary search O(log_2(n)) Selection sort O(n^2) Insertion sort O(n^2) Merge sort O(n log_2(n)) Quick sort O(n log_2(n)) Plug in for n=1000000 and estimate the values. That would give... Algorithm Running time Estimate for n=1000000 ------------------------------------------------- Linear search O(n) 1000000 Binary search O(log_2(n)) about 20 Selection sort O(n^2) 10^12, or 1 trillion, 1 with 12 zeros after it Insertion sort O(n^2) 10^12 also Merge sort O(n log_2(n)) about 1000000 * 20 Quick sort O(n log_2(n)) about 1000000 * 20 And that used the fact that log_2(1000000) is about 20. Why? The rules of logs you want to remember are... log_2(2) = 1 log_2(x^k) = k * log_2(k) log_2(x * y) = log_2(x) + log_2(y) 1000 is close to 1024, which is 2^10 So 1000000 is 1000*1000, which is close to 1024 * 1024, which is 2^10 * 2^10, which is 2^20 So, log_2(1000000) is close to log_2(2^20), which is 20 * log_2(2) = 20. 4. Given a list of 1 million unsorted numbers, what is the fastest way you know of to find out if 42 is in the list of numbers? About how many basic operations will it take? This is a trick question. Consider two ways to do it. First, use linear search. That takes 1 million operations to look at all the numbers on the list. Second, sort the list and then use binary search. Sorting takes O(n log_2(n)), which for n=1000000 we said above takes about 20 million steps. After sorting, binary search would take about 20 steps to find if 42 is in the list. The total amout of time is 20 million + 20. The total time is longer if you sort and then use binary search. Why? Because sorting is kind of overkill for just finding if one number is in the list. You have done more work than is really needed. If you just want to find one number in the list, linear search is the fastest way we know how. If you're going to be looking for lots of different numbers, it might be best to sort them first and then use binary search. Nice trick questions, right. 5. Given a list of 1 million sorted numbers, what is the fastest way you know of to find out if 42 is in the list of numbers? About how many basic operations will it take? With the numbers already sorted, linear search still takes 1 million operations. But now we can use binary search without having to sort the numbers first, and binary search takes about 20 operations. So the fastest is binary search, with about 20 operations. 6. Given the following numbers, show what the list looks like after each step of selection sort. 4 8 1 6 3 2 9 0 Here is what the list of numbers looks like after each "find the smallest and put it where it should be". 0 8 1 6 3 2 9 4 0 1 8 6 3 2 9 4 0 1 2 6 3 8 9 4 0 1 2 3 6 8 9 4 0 1 2 3 4 8 9 6 0 1 2 3 4 6 9 8 0 1 2 3 4 6 8 9 7. Given the same list of numbers, show what the list looks like after each step of insertion sort. Here is what the list of numbers looks like after each "make sure the first blah many numbers is in order". 4 8 1 6 3 2 9 0 1 4 8 6 3 2 9 0 1 4 6 8 3 2 9 0 1 3 4 6 8 2 9 0 1 2 3 4 6 8 9 0 1 2 3 4 6 8 9 0 0 1 2 3 4 6 8 9 8. And also merge sort. Let's do the version of merge sort where we sort pairs, then 4's, etc. After sorting pairs, we have 4 8, 1 6, 2 3, 0 9 Then after merging the first two pairs into a sorted group of 4, we have 1 4 6 8, 2 3, 0 9 Then after merging the last two pairs into a sorted group of 4, we have 1 4 6 8, 0 2 3 9 THen after merging these two groups of four, we have 0 1 2 3 4 6 8 9 9. Encrypt the following message using a caesar cipher by shifting all letters by 5. Try to take... The encrypted message would be: Ywd yt yfp... 10. For each of the following, what is the final value of x? Show your work. a. int x = 5 / 2+1; 2 + 1 3 b. float x = 1+5.0 / 2 ; 1 2.5 3.5 c. int x = 3; x++; x--; x+= 3; 3; 4; 3; 6; d. char x = CHAR_MIN; x--; // char is 1 byte, 8 bits -128; 127 range on n bits, signed, is -2n-1 up to 2n-1-1 e. int x = (1 <= 2 && 2 <= 1); T && F F 0 printf("%i\n", x); f. int x = 4; int *y = &x; *y += 1; 4; y is a pointer to x; whatever is in the location y points to, y has the address of x; add 1 to it; y points to x, so x becomes 5; g. int x = 15 % 4; 3 11. For each of the following boolean expressions, determine whether it is true or false. Show your work. a. (3 < 10 || 10 < 3) T || 10 < 3 T b. (! 4 < 5 && 5 == 5) ! T && 5 == 5 F && 5 == 5 F c. (3 != 4 && 4 == 3) T && 4 == 3 T && F F d. (3 < 4 && 5 <= 4) T && 5 <= 4 T && F F 12. Memorize program. Write down the code for one of the following programs: basic_for2.c, basic_while.c, basic_smallest.c, basic_string2.c, basic_if2.c On the test, I'll pick one in particular to ask you to write down. 13. Be the computer. For each of the following, keep track of the values of all the variables as the code runs - as we have done on the board in class. // a. int fun1(int x, int y) { // x = 3 16 y = 4 x = y * y; return x; // return 16 } int fun2(int *z) { // z = address of w from main, so z points to w in main *z *= 2; // multiplies w in main by 2 return *z; // return 32 } int main() { // x = 3 32 w = 4 16 32 int x = 3, w = 4; w = fun1(x, w); // set w to 16 x = fun2(&w); // set x to 32 printf("%i\n", x); // print 32 to the screen return 0; } // b. char msg[10] = "abcd"; int i; for(i=strlen(msg)-1; i >= 0; i--) { printf("%c\n", msg[i]); } printf("\n"); /* msg: "abcd", never changes i: 3, then 2, then 1, then 0, then -1 screen: d c b a Note: this prints the string backwards */ // c. int x = 42; int i = 0; char msg[10]; while (x > 0) { msg[i] = '0' + (x % 4); x /= 4; i++; } msg[i] = "\0"; /* x: 42, then 10, then 2, then 0 i: 0, then 1, then 2, then 3 msg: // using ? to mean "don't know what's there yet"... "??????????", then "2?????????", then "22????????", then "222???????", then "222\0??????", which is "222" if printed to the screen Note: this converts x to "base 4" and puts that into the string msg (actually in reverse order, so the "one's place" is the beginning of the string). */