Sept. 16 Intro to pa1, finish Chap. 5
Collect hw1 (or next time), hand out paper strips with turnin usernames, also lab partner names.
Can construct turnin username from rule: Up to 5 letters from your last name, followed by more letters of your first name until they run out or make 7 chars in all.
Initial password is "passwd", change it as soon as possible to protect your turned in files.
Note new Resources at end of class web page: generics overview and FAQ.
Sent test message out yesterday.
Qual solution: $cs210/pa1, start on pa1.
Intro to pa1
First get your qual solution or mine actually working in your IDE.
Then mods to do:
End up with: using dotted lines for implements, more solid for extends:
BinCollection interface
:
:
AbstractBinCollection abstract class with common
code
/
\
/
\
SimpleBinCollection WorstFitBinCollection two concrete
subclasses
This is a good setup for the case of two implementations for one service described by an API, i.e., an interface.
Debugging
Basic ideas, not using a debugger (and thus universally usable)
More advanced debugging, using the IDE's debugger: covered in lab
Back to Chap. 5--study through pg. 186
Last time “finished” chap. 5, the parts we will cover.
Guide to Chap. 5:
5.1, 5.2—all
5.3—can skip, don’t worry about sigma notation (Σ)
5.4—just Big-Oh
5.5—log, important
5.6—binary search, important, except skip 5.6.3
5.7, 5.8—read
Note we are covering Big-Oh, but not the other Big’s and Little’s.
Working with arrays
Assign an element: a[i] = 10 This is O(1) even for large i, because spot in array is computed by simple arithmetic. Similarly accessing an array element.
Shifting elements down one to make a free spot in an array:
for (i = n; i >= 5; i++)
a[i+1] = a[i]
This is n-5 passes each O(1), so T = O(n)
It’s fine to do this a few times, but if it’s in a bigger loop, it can get expensive.
For example, suppose each of n input items is placed somewhere in a growing array by making space for it this way. Then for item j, it takes O(j) to insert it For the whole thing, it costs O(1 + 2 +3 + … + n) = O(n2).
There is a math formula 1 + 2 +3 + … + n = n(n-1)/2. that makes a neat proof for this. But for our purposes, we can observe that the average value of the added items is n/2, and there are n of them, so the total must be O(n2).
pg. 181—more on logs
Note that "log" defaults to log base 2 here
Theorem 5.4 logB(N) = O(log N) i.e., logs of all bases grow at the same rate for large N.
logB N = log2 N / log2 B = log N / log B so all log-bases are related by multiplicative constants, which we discard in Big-Oh analysis.
For example, for B=10 ("common log"), log2 (10) = 3.32, so log 10(N) = 3.32 * log (N)
Thus we can be apparently sloppy and say O(log N) with a clear conscience.
Number Representation
8 bit integers—what are they called in Java? Answer: type “byte”, not used much in ordinary apps.
MSB = most significant bit, shows sign of number
Zero and positive numbers:
0 = 00000000 in binary
1 = 00000001
2 = 00000010
… ones advance left, until they have taken over all the bits except the MSB
? = 01111111 highest positive number, = 27 – 1 = 127
Negative numbers
-1 = 11111111
-2 = 11111110
-3 = 11111101
… zeroes advance left, until they have taken over all the bits except the MSB
-? = 10000000 most negative number, = - 27 = -128
Full number of 8-bit integers = 1 + (27
– 1) + 27
= 2*27 = 28
zero positives negatives
Range is [-128, 127]
Similarly--
16 bit integers, shorts in Java, have 215 – 1 positives, 1 zero, and 215 negatives, totaling 216 16-bit integers. Range is [-32K, 32K-1]
32 bit integers, ints in Java, have 231 – 1 positives, 1 zero, and 231 negatives, totaling 232 32-bit integers. Range is [-2G, 2G -1]
64 bit integers, longs in Java, have 263 – 1 positives, 1 zero, and 263 negatives, totaling 264 64-bit integers. Range is [-8192T, 8192T -1]
Important binary magnitudes:
kilo K = 210 = 1024, approx. 103
mega M = 220 = 10242, approx. 106
giga G = 230 = 10243, approx. 109
tera T = 240 = 10242, approx. 1012
We see that the number of n-bit numbers = 2n and thus the number of bits for N numbers is log2(N), very slowly growing with N. If we add one more bit, we can represent twice as many numbers.
Section 5.6 Searching an Array for a value
Sequential Search
Suppose int array of length n:
for (i=0; i < a.length; i++)
if (a[i] == x)
return i;
We see the body is O(1), just array access, etc., and the number of passes is up to n, so the worst case performance is O(n).
OK for occasional use, but like shifting an array down one, not so good if it’s inside a loop.
Binary Search—much better, used in serious apps
Needs an ordered array. Look at int array example, using code from Weiss, pg. 185 specialized to int array case. Note that computing with an int array will be much faster than with an object array as required by the generic code, because the data is concentrated in memory in a tight array of int, not hung by references on a "spine" of reference spots. With today's processors bringing in "cache lines" of say 64 bytes at a time from memory, this makes a real difference.
// ordered array of ints for binary search, set up in
// the caller of binSearch:
int[] a = { -10, -2, 5, 9, 50, 1000};
// 0
1 2 3 4 5
public static int binSearch( int [] a, int x)
{
... no time to fill in code
}
Example: Search for x = 5:, call binSearch(a, 5), get back return value of 2 because the value 5 sits at array spot 2.
Idea of binary search: split the array into two halves, the low half and the high half of values, split by the middle value, say v. Compare the target x with v, and if x is below v, it means that x is in the first half of the array, whereas if x is above v, it's in the high half, or else if v=x we found x already and we're done. Then similarly process the half array we found. Repeated halvings of the array quickly home in on the target.
Question: so what's the resulting T(N)?