CSc 331 - Spring 2018
Lab Exercise #4

Preparation

Additional Information / Guidelines

Exercise 1:

Plan, code and "test" a ReducedFraction class that extends the Fraction class from Lab1. ReducedFraction's are always stored in lowest terms. Use your own implementation for Fraction - or if you prefer use the one in ~hohman/331/s18/labs/lab4

You will need to code appropriate constructors and override toString. (Recall that constructors are not inherited.) You will also need to make a couple of small changes to your Fraction code.

Java "hint": For a constructor "call" like new ReducedFraction(3,6), you want to say super(1,2) - i.e. first reduce the given values by their gcd, then call super with the reduced values. But the call to super must be the first statement in a constructor! The standard Java trick is to code helper function(s) that create the required values from the given values - and then use function calls as the parameters for super. (The member variables in Fraction will remain private.)

For the purposes of this Java programming exercise, the following main method ...


    public static void main(String[] args) {
        ReducedFraction rf1 = new ReducedFraction(2,4);
        System.out.println( "rf1 = " + rf1);
        rf1 =  new ReducedFraction(7, 4);
        System.out.println( "rf1 = " + rf1);
        rf1 =  new ReducedFraction(3);
        System.out.println( "rf1 = " + rf1);
        rf1 =  new ReducedFraction(0, 5);

        System.out.println();
        for (int i = 0; i < 16; i++ ) {
            rf1 = new ReducedFraction(i, 6);
            System.out.print(rf1 + "  ");
        } 
        System.out.println();
    }

should produce output very much like ...


rf1 = 1/2
rf1 = 7/4
rf1 = 3/1

0/1  1/6  1/3  1/2  2/3  5/6  1/1  7/6  4/3  3/2  5/3  11/6  2/1  13/6  7/3  5/2 

Exercise 2:

In preparation for things to come, let's code a FractionSet class that contains a set of ReducedFraction's. (You might imagine a ShoppingCart class that contains a set of Product's and a customer id.)

(Copied from the Oracle documentation.) There are three general-purpose Set implementations — HashSet, TreeSet, and LinkedHashSet. Which of these three to use is generally straightforward. HashSet is much faster than TreeSet (constant-time versus log-time for most operations) but offers no ordering guarantees. If you need to use the operations in the SortedSet interface, or if value-ordered iteration is required, use TreeSet; otherwise, use HashSet. It's a fair bet that you'll end up using HashSet most of the time.

LinkedHashSet is in some sense intermediate between HashSet and TreeSet. Implemented as a hash table with a linked list running through it, it provides insertion-ordered iteration (least recently inserted to most recently) and runs nearly as fast as HashSet. The LinkedHashSet implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet without incurring the increased cost associated with TreeSet.

Implement the set as a LinkedHashSet. Hint: you will need to overide some Object class methods - as discussed in the lecture. You might also find the hash method from the Objects class in the java.util package useful.

FractionSet will contain the following methods:

And just to use a couple of other features of Java Collection classes ...

The union function can "easily" be coded in about 3 lines with the addition of another constructor. All of the basic Set implementations have constructors like public LinkedHashSet(Collection<E> C) which constructs a new LinkedHashSet with the same elements as given collection C. So here you can write a 1-line constructor that takes a Set<ReducedFraction> parameter.

Executing the class DemoFractionSet should produce output very much like the following. (The "n-1 commas" format shown is only worth a mark or 2 ...)


$ java DemoFractionSet
The set contains 0 elements.
A = {}
A = {1/3}
Duplicate ignored.
The set contains 2 elements.
A = {1/3, 1/4}
B = {2/7, 1/3}
The union is contains {2/7, 1/3, 1/4}

Set A contains 5 elements.
A = {0/1, 1/2, 1/1, 3/2, 2/1}
B = {1/2, 2/3, 5/6, 1/1, 7/6, 4/3, 3/2}
A union B = {1/2, 2/3, 5/6, 1/1, 7/6, 4/3, 3/2, 0/1, 2/1}

Exercise 3:

Code a SortedFractionSet class that contains a set of ReducedFraction's - but this time in ascending order. This is the same task as Exercise 2 but with a TreeSet implementation for the Set of ReducedFractions. Elements in a TreeSet must implement the Comparable interface.

Start with a copy of your code for the FractionSet class - you will not have to do much! You will need to add a bit to the Fraction (or ReducedFraction?) class.

To code compareTo, you might want to note that a/b = c/d iff ad = bc. This relationship is also true for < and >.

Executing the class DemoFractionSet should produce output very much like


$ java DemoSortedFractionSet
The set contains 0 elements.
A = {}
A = {1/3}
Duplicate ignored.
The set contains 2 elements.
A = {1/4, 1/3}
B = {2/7, 1/3}
The union is contains {1/4, 2/7, 1/3}

Set A contains 5 elements.
A = {0/1, 1/2, 1/1, 3/2, 2/1}
B = {1/2, 2/3, 5/6, 1/1, 7/6, 4/3, 3/2}
A union B = {0/1, 1/2, 2/3, 5/6, 1/1, 7/6, 4/3, 3/2, 2/1}

Exercise 4:

And now for a small Map exercise. Recall that a map / dictionary / Perl hash "maps" keys onto values. There are no duplicate keys. The Java Map interface has methods

We can iterate over the keys in a Map using its keySet Set, over the values using its values() Set, or over its key-value pairs using it entrySet() Set of Map.Entry elements.

Complete the WordCounter class given in the lab4 directory - so that it will count the number of occurrences of each word in standard input. Words are separated by whitespace. Count only "interesting" words - here interesting means words with length >= 4. This count is not case-sensitive i.e. "Cats" and "cats" are the same word. But do not deal with punctuation i.e. "cats" and "cats." are different words.

Recall that you can redirect a file to standard input using a Linux command like java WordCounter <infile1

Submit:

This assignment is due at the beginning of the Tuesday lab class next week (3:30 p.m.) - and the submit program will enforce this