Overview
average
must use O(1) space.long
values, so the average is likely to be
slightly off if the sum of the values is not a multiple of the length.put
(or enqueue
) method.How will remove be called?
The client code will call
remove
when they want to remove elements they have just seen. A typical instance.
Iterator<String> it = pq.iterator();
while (it.hasNext()) {
String s = it.next();
if (some_complicated_logic_that_you_do_not_know(s)) {
it.remove();
} // if
} // while
_Does it also have to work with for-each?
No, since there’s no iterator that the client explicitly accesses.
Can we have a point of extra credit for the “minor” typo?
Sure.
Should average
return the same value as if we did it with arbitrary length integers?
Yes.
There’s some evidence that programmers make mistakes, particularly in loops in code.
It is good to have tools that let us
When reasoning about programs, we normally pay attention to the “state”. Most typically, the values of variables on the stack and the heap. (Pictures help.)
We can go from the start to the finish:
We can also work backwards from goal to origin.
Loops are a common point of failure, so we do this analysis most commonly with loops.
A loop invariant is a statement about the state of the program
For arrays, pictures are often more helpful than text.
+---------------+-----------------+
| sorted | unknown |
+---------------+-----------------+
i length
So far
Invariant holds
Loop
Invariant holds
That is, when the loop terminates, the invariant still holds. We must also show that the loop terminates.
In the binary search from Friday, some folks had non-terminating code in a few situations (particularly when I forced it upon you).
while (lb <= ub) {
if (vals[mid] < goal)
lb = mid;
else ...
}
If lb
is 0 and ub
is 1, and the value we are searching for is at
position 1, then, mid
is 0, vals[mid] < goal
, so lb = mid = 0
.
Traditionally, once we prove that the loop has terminated and that the invariant holds, we can reach an appropriate conclusion.
E.g., If our invariant is “If the value is in the array, then it’s between lb and ub” and our loop test is as above, once the loop exits, we know that lb > ub, there are no values in that range, so we know the value is not in the array.
Inputs:
Goal:
Return:
Some questions
Idea to approach it: Swap elements from the outside of the array, moving in.
Another idea: Work from the middle
+------+-------+--------+---------+
|unkno.|<=piv | > piv | unknown |
+------+-------+--------+---------+
| | | | |
0 i center j length
Look to the left of i and the value at j.
When do we stop?
+--------------+--------+---------+
| <=piv | > piv | unknown |
+--------------+--------+---------+
| | | |
0,i center j length
It appears that we now need to do something a bit different. Now,
Note: We’ll also have to do similar work when j = length and i > 0.
Questions to ignore for now
A different invariant
+------+----------------+---------+
|<= piv| unknown | > piv |
+------+----------------+---------+
| | | |
0 s l length
Rephrased in English (Mathish)
Policy:
Termination (when l <= s):
Progress:
+------+---------+
|<= piv| > piv |
+------+---------+
| | |
0 s,l length
Can s
ever be greater than l
? No (Analysis discussed)
Note: How are we sure that the invariant holds when we start our algorithm?
+------+----------------+---------+
|<= piv| unknown | > piv |
+------+----------------+---------+
| | | |
0 s l length
If s
starts as 0 and l
starts as length, there’s nothing in the
two border sections, everything is unknown, and the invariant holds.
You have an array with three values, which we’ll call red, white, and blue. They are in no particular order. Your goal is to rearrange it so that all of the red are at the left, all the blue are at the right, and all the white are in between.
Input:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| b | r | w | w | r | b | w | r | w | w | w | r | w | b | r | b | w |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Output
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| r | r | r | r | r | w | w | w | w | w | w | w | w | b | b | b | b |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Come up with an invariant, do the other anlysis.
+----------------+---------+----------+-------+--------------+
| red | unknown | white |unknown| blue |
+----------------+---------+----------+-------+--------------+
| | | | | |
0 r w x b length
In Mathglish,
The prior invariant turns out not to work well. So we switch to the following one. Note that that one also includes clear steps for maintaining the invariant while decreasing the size of the unknown section.
+----------------+--------------+-------------+--------------+
| red | white | unknown | blue |
+----------------+--------------+-------------+--------------+
| | | | |
0 r i b length