CS62  Spring 2011  Lecture 13
video

http://www.youtube.com/watch?v=yX8yrOAjfKM
(Matrix Windows XP)
admin
 quiz Friday
 assignment 4 out
 a quick hint about how to tell if you're off the end
 lab today: look at the two towers problem in the book (Section 8.7)
number representation in Java
 As we've mentioned before, numbers are stored in binary
 For example, the first few binary numbers are:
0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
 To calculate the value of a binary number:
 digit/position i in the binary number represents a value of 2^i
 this is similar to decimal number representation where digit/position i represents a value of 10^i
 sum up the value of all of the digits where there is a 1
 101 = 2^0 + 2^2 = 5
 11011 = 2^0 + 2^1 + 2^3 + 2^4 = 1 + 2 + 8 + 16 = 27
 101010 = 2^1 + 2^3 + 2^5 = 2 + 8 + 32 = 42
 In Java, there is another version of Integer.parseInt where we can pass a second parameter that is the "base" of the number we're trying to interpret. For binary, the base is 2.
 System.out.println(Integer.parseInt("101010", 2));
 42
 ints in Java are stored with 32 bits and longs with 64 bit
 for now, we won't talk about how negative numbers are represented, but the basic idea is to use one of the bits to represent the sign and then the remaining bits for the number portion (it's a bit more complicated than this... Java uses a twoscomplement representation for those who took cs52
More operators
 we saw the ternary operator
 Java has a number of "bitwise" operators that allow us to manipulate the individual bits of a number
 bit shifting operators
 << (left shift)
 n << p shift the number n, p bits to the left, filling in the lower order bits with zeros
 examples
 2 << 1 = 10 << 1 = 100 = 4
 5 << 1 = 101 << 1 = 1010 = 10
 6 << 3 = 110 << 4 = 110000 = 48
 shifting the bits up one is equivalent to doubling the number
 so, shifting the bits up p positions is equivalent to doubling the number p times, or multiplying by 2^p  >> (right shift)
 n >> p shift the number n, p bits to the right, throwing away the lower order bits
 examples
 2 >> 1 = 10 >> 1 = 1
 5 >> 1 = 101 >> = 10 = 2
 13 >> 2 = 1101 >> 2 = 11 = 3
 14 >> 2 = 1110 >> 2 = 11 = 3
 shifting the bits down one is equivalent to dividing the number by 2 and rounding down
 so, shifting the bits down by p positions, is equivalent to divising by 2 p times, or dividing by 2^p and rounding down
 be careful about overflow errors because of shifting too far to the left or right. Remember, an int is only 32 bits (and really 31 with a sign bit).
 bitwise logical operators
 we've seen && and  for booleans, there are equivalent operators on the bit level
 show truth tables for "AND" and "OR"
 the '&' and '' operator perform bitwise "AND" and "OR" between two numbers
 14 & 3 = 1110 & 11 = 10 = 2
 14  3 = 1110  11 = 11 = 3
 12 & 5 = 1100 & 101 = 100 = 4
 12  5 = 1100  101 = 101 = 5
 and, if you're curious '^' is the bitwise "XOR" operator
 A few operations
 how would you check if the last bit of an int num was a 1?
 num & 1 == 1
 how would you check if the nth bit of an int num was 1?
 num >> n & 1 == 1
implementing a Queue
 LinkedList
 What kind do we need to use?
 The easiest is to use a singly linked list
 add elements to the tail/end
 remove elements from the head/front
 Could also use a doubly linked list (though why, if you don't need to)
 ArrayList
 Does it work well?
 Array based
 what if we wanted to implement it using an array, with the additional knowledge that we know the largest capacity required?
 keep track of where our head is and where our tail is and have the data wrap around at the end of the array
 always add at the tail
 always remove from the head
 is there an easy way to calculate indices?
 use modular arithmetic!
 if we want to increment the head, for example:
 instead of: headIndex++
 headIndex = (headIndex + 1) % data.length
 look at ArrayQueue in
StacksAndQueues code

http://java.sun.com/javase/6/docs/api/java/util/Queue.html
postfix notation (aka reverse polish notation)

http://xkcd.com/645/
 what we normally think of as algebraic notation is called infix notation
 the operators are in between the operands
 2 + 2
 (1 + 3) * 4
 postfix notation puts the operator at the end of the arguments, that is operators follow the operands
 3 4 +
 2 5 *
 we can make more complex expression
 (2 + 4) * 5
 2 4 + 5 *
 (4  1) * (3 + 5)
 4 1  3 5 + *
 notice that we no longer need parenthesis since there is no ambiguity
 the algorithm to handle postfix notation is as follows:
 Read the next token from input
 If the token is a value
 push it onto the stack
 Otherwise, the token is an operator
 It is known a priori that the operator takes n arguments
 If there are fewer than n values on the stack
 (Error) The user has not input sufficient values in the expression
 Else, Pop the top n values from the stack
 Evaluate the operator, with the values as arguments
 Push the returned results, if any, back onto the stack
 try a few:
 1 2 3 4 5 6 * +  / +
 2 3 + 5 * 2 2 2 * * +
 1 2 + 8 3 * 
 7 6 5 + 1 + + +
 converting from infix to postfix
 5 + ((1 + 2) * 4)  3
 1 2 + 4 * 5 + 3 
 5 1 2 + 4 * 3 
 ((9  4) * 5)/2 + 4 * 5
 9 4  5 * 2 / 4 5 * +
 4 5 * 2 5 9 4  * / +
 many different ways to do it!
 prefix notation is the reverse of postfix notation
 + 2 3
 +  2 3 4