Algorithms and OOD (CSC 207 2014F) : EBoards

CSC 207.01 2014F: Extra Session 13 (Thursday, 4 December 2014)


Topics to discuss

Question Number One

Main goal is that you can efficiently compute (x^k) % p. Once you've written that, use it for primality testing by repeatedly: picking a random number, a, between 0 and p-1 (inclusive), compute (a^(p-1)) % p. If it's not 1, p is not prime. If you've done enough of these tests, you're pretty sure that p is prime.

If we compute x^k and x is 100 digits and k is a 100 digits, we will end up with a number that is approximately 2^100 digits (maybe not quite so many, but enough that it's a pitn). But whether you do that computation sensibly or senselessly, you're doing multiplications. So you can use mod before or after every multiplication. Because (a*b)%c == (a%c) * (b%c).

Question Number Four

General: Removing values from open hash tables (as opposed to chained hash tables). Open hash tables are ones in which you do probing. We do linear probing in this problem because it's easier to handle.

Here's why it's potentially problematic. Suppose we have an array of size 20, and an offset of 7, v1's hash code is 1, v2's hash code is 8, v3's hash code is 21. When we put them in ... v1 goes in 1 (easy), v2 goes in 8 (easy). v3 conflicts at 1, v3 conflicts 8, v3 goes into position 15. Remove v1. Can we still find v2? Yes. But we can't find v3. So we have to rearrange after removing v1. Your inclination is to move v2. That's a bad inclination.

Morals: You will to move things. You will have to look for a bit to find all the things that might move. We look in 8 (v1, doesn't move), 15 (v3, moves), 2 (nothing, we're done). The magic of statistics tells us that we won't have to look very far.

Question Number Three

Yay! Tree traversal.

To traverse a tree preorder, depth-first, left-to-right, we (a) store intermediate values on a stack (intermediate value == node or a value), (b) given a node, we add things to the stack in the order right, left, value.

To traverse a tree preorder, depth-first, right-to-left, we (a) store intermediate values on a stack (intermediate value == node or a value), (b) given a node, we add things to the stack in the order left, right, value.

To traverse a tree inorder, depth-first, left-to-right, we (a) store intermediate values on a stack (intermediate value == node or a value), (b) given a node, we add things to the stack in the order right, value, left.

To traverse a tree preorder, breadth-first, left-to-right, we (a) store intermediate values in a queue (intermediate value == node or a value), (b) given a node, we add things to the stack in the order value, left, right.

To traverse in general, we should only need to specify the linear structure and the order in which we add the three parts of a node.

The "dictionary" called traversalStructures givees something that builds the appropriate linear structure. The "dictionary" called traversalOrders gives the order. The method called unpack unpacks a node into the linear structure (e.g., value, then left, then right).

The next method checks the linear structure and ...

Problem Two

Random linear structures follow the "it's hard to predict what get will return" policy.

Challenge: Remove the thing that was just returned by next.

Biggest problem students have had: Make sure that every remaining element gets visited by successive calls to next. In their code, if there were five elements, and I called "next, next, remove, next, next, next", the last next would be an error.

You can tell this is happening because when the experiment tries to remove all of the a's, it misses some.

    while (this.hasNext())
      {
        if (this.next.equals("a"))
          this.remove();
      } // while