collections(1)

Upload: tholang-kopano-kumalo

Post on 05-Apr-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Collections(1)

    1/8

    UNIVERSITY OF JOHANNESBURG

    FACULTY OF MANAGEMENTAPPLIED INFORMATION SYSTEMS

    ND (IT) APB CAMPUS

    BTP22A2 TECHNICAL PROGRAMMING 2A

    Collections Exercises [?marks] Complete by: 09 March 2012

    Instructions:

    Write all the programs and demonstrate them to your tutor. Make sure that you sign the PracticalWork Completion Register not later than the final date for the practical exercises.

    Exercise 1Rewrite the following PhoneDirectory class so that it uses a TreeMap to store

    directory entries, instead of an array. (Use Javadoc comments to explain advantages of

    using a TreeMap over an array for such a class):

    /**

    * A PhoneDirectory holds a list of names with a phone number for each

    *name. It is possible to find the number associated with a given name,

    *and to specify the phone number for a given name.

    */

    public class PhoneDirectory {

    /**

    * An object of type PhoneEntry holds one name/number pair.

    */private static class PhoneEntry {

    String name; // The name.

    String number; // The associated phone number.

    }

    private PhoneEntry[] data; // Array that holds the name/number pairs.

    private int dataCount; // The number of pairs stored in the array.

    /**

    * Constructor creates an initially empty directory.

    */

    public PhoneDirectory() {

    data = new PhoneEntry[1];

    dataCount = 0;

    }

    /**

    * Looks for a name/number pair with a given name. If found, the index

    * of the pair in the data array is returned. If no pair contains the

    * given name, then the return value is -1. This private method is

    * used internally in getNumber() and putNumber().

    */

    private int find( String name ) {

    for (int i = 0; i < dataCount; i++) {

    if (data[i].name.equals(name))

    return i; // The name has been found in position i.

    }

    return -1; // The name does not exist in the array.

    }

  • 7/31/2019 Collections(1)

    2/8

    2

    /**

    * Finds the phone number, if any, for a given name.

    * @return The phone number associated with the name; if the name does

    * not occur in the phone directory, then the return value is null.*/

    public String getNumber( String name ) {

    int position = find(name);

    if (position == -1)

    return null; // There is no phone entry for the given name.

    else

    return data[position].number;

    }

    /**

    * Associates a given name with a given phone number. If the name

    *already exists in the phone directory, then the new number replaces

    *the old one. Otherwise, a new name/number pair is added. The name and

    *number should both be non-null. An IllegalArgumentException is thrown

    *if this is not the case.*/

    public void putNumber( String name, String number ) {

    if (name == null || number == null)

    throw new IllegalArgumentException("name and number cannot be null");

    int i = find(name);

    if (i >= 0) {

    // The name already exists, in position i in the array.

    // Just replace the old number at that position with the new.

    data[i].number = number;

    }

    else {

    // Add a new name/number pair to the array. If the array is already

    // full, first create a new, larger array.if (dataCount == data.length) {

    PhoneEntry[] newData = new PhoneEntry[ 2*data.length ];

    System.arraycopy(newData,0,data,0,dataCount);

    data = newData;

    }

    PhoneEntry newEntry = new PhoneEntry(); // Create a new pair.

    newEntry.name = name;

    newEntry.number = number;

    data[dataCount] = newEntry; // Add the new pair to the array.

    dataCount++;

    }

    }

    } // end class PhoneDirectory

    Exercise 2In mathematics, several operations are defined on sets. The union of two sets A and B isa set that contains all the elements that are in A together with all the elements that are inB. The intersection of A and B is the set that contains elements that are in both A and B.The difference of A and B is the set that contains all the elements of A except for thoseelements that are also in B. Suppose that A and B are variables of type set in Java. Themathematical operations on A and B can be computed using methods from the Setinterface. In particular:

    A.addAll(B) computes the union of A and B; A.retainAll(B) computes the intersectionof A and B; and A.removeAll(B) computes the difference of A and B. (These

  • 7/31/2019 Collections(1)

    3/8

    3

    operations change the contents of the set A, while the mathematical operationscreate a new set without changing A, but that difference is not relevant to thisexercise.)

    For this exercise, you should write a program that can be used as a set calculator forsimple operations on sets of non-negative integers. (Negative integers are not allowed.)A set of such integers will be represented as a list of integers, separated by commasand, optionally, spaces and enclosed in square brackets. For example: [1,2,3] or [17, 42,9, 53, 108]. The characters +, *, and - will be used for the union, intersection, anddifference operations. The user of the program will type in lines of input containing twosets, separated by an operator. The program should perform the operation and print theresulting set. Here are some examples:

    Input Output------------------------- -------------------

    [1, 2, 3] + [3, 5, 7] [1, 2, 3, 5, 7][10,9,8,7] * [2,4,6,8] [8][ 5, 10, 15, 20 ] - [ 0, 10, 20 ] [5, 15]

    To represent sets of non-negative integers, use sets of type TreeSet. Read

    the users input, create two TreeSets, and use the appropriate TreeSet method to

    perform the requested operation on the two sets. Your program should be able to readand process any number of lines of input. If a line contains a syntax error, your programshould not crash. It should report the error and move on to the next line of input. (Note:To print out a Set, A, of Integers, you can just say System.out.println(A). Ive

    chosen the syntax for sets to be the same as that used by the system for outputting aset.)

    Exercise 3The fact that Java has a HashMap class means that no Java programmer has to write an

    implementation of hash tables from scratchunless, of course, that programmer is acomputer science student.

    For this exercise, you should write a hash table in which both the keys and the valuesare of type String. (This is not an exercise in generic programming; do not try to write ageneric class.) Write an implementation of hash tables from scratch. Define the followingmethods: get(key), put(key,value), remove(key), containsKey(key),and size().

    Remember that every object, obj, has a method obj.hashCode() that can be usedfor computing a hash code for the object, so at least you dont have to define your ownhash function. Do not use any of Javas built-in generic types; create your own linkedlists using nodes. You do not have to worry about increasing the size of the table when itbecomes too full.

    You should also write a short program to test your solution.

    Exercise 4The following example subroutine:

    /**

  • 7/31/2019 Collections(1)

    4/8

    4

    * Add a page reference to the index.

    */

    void addReference(String term, int pageNum) {

    TreeSet references; // The set of page references that we// have so far for the term.

    references = index.get(term);

    if (references == null){

    // This is the first reference that we have

    // found for the term. Make a new set containing

    // the page number and add it to the index, with

    // the term as the key.

    TreeSet firstRef = new TreeSet();

    firstRef.add( pageNum ); // pageNum is "autoboxed" to give an Integer!

    index.put(term,firstRef);

    }

    else {

    // references is the set of page references

    // that we have found previously for the term.// Add the new page number to that set. This

    // set is already associated to term in the index.

    references.add( pageNum ); // pageNum is "autoboxed" to give an

    Integer!

    }

    }

    concerns the problem of making an index for a book.A related problem is making a concordance for a document. A concordance lists everyword that occurs in the document, and for each word it gives the line number of everyline in the document where the word occurs. The subroutines for creating an index canalso be used to create a concordance.

    The only real difference is that the integers in a concordance are line numbers ratherthan page numbers.

    Write a program that can create a concordance. The document should be read from aninput file, and the concordance data should be written to an output file. Check up theindexing subroutines from the Java Collections API (Oracle website) and use them,modify them to write the data to TextIO instead of to System.out. (You will need tomake these subroutines static.) The input and output files should be selected by the userwhen the program is run. The following sample program:

    import java.util.ArrayList;

    import java.util.Collections;

    import java.util.TreeMap;

    import java.util.Comparator;

    /**

    * This program will read words from an input file, and count the

    number of occurrences of each *word. The word data is written to an

    output file twice, once with the words in alphabetical order *and once

    with the words ordered by number of occurrences. The user specifies

    the input file *and the output file.

    *

    * The program demonstrates several parts of Java's framework for

    generic programming: *TreeMap, List sorting, Comparators, etc.

  • 7/31/2019 Collections(1)

    5/8

    5

    */

    public class WordCount {

    /*** Represents the data we need about a word: the word and the number of

    times it has been *encountered.

    */

    private static class WordData {

    String word;

    int count;

    WordData(String w) {

    // Constructor for creating a WordData object when

    // we encounter a new word.

    word = w;

    count = 1; // The initial value of count is 1.

    }

    } // end class WordData

    /**

    * A comparator for comparing objects of type WordData according to

    their counts. This is used *for sorting the list of words by frequency.

    */

    private static class CountCompare implements Comparator {

    public int compare(WordData data1, WordData data2) {

    return data2.count - data1.count;

    // The return value is positive if data2.count >

    data1.count.

    // I.E., data1 comes after data2 in the ordering if there

    // were more occurrences of data2.word than of data1.word.

    // The words are sorted according to decreasing counts.

    }} // end class CountCompare

    public static void main(String[] args) {

    System.out.println("\n\n This program will ask you to select an

    input file");

    System.out.println("It make a list of all the words that occur in

    the file");

    System.out.println("along with the number of time that each word

    occurs.");

    System.out.println("This list will be output twice, first in

    alphabetical,");

    System.out.println("then in order of frequency of occurrence with

    the most");System.out.println("common word at the top and the least common

    at the end.");

    System.out.println(" After reading the input file, the program

    asks you to");

    System.out.println("select an output file. If you select a file,

    the list of");

    System.out.println("words will be written to that file; if you

    cancel, the list");

    System.out.println("be written to standard output. All words are

    converted to");

    System.out.println("lower case.\n\n");

    System.out.print("Press return to begin.");

  • 7/31/2019 Collections(1)

    6/8

    6

    TextIO.getln(); // Wait for user to press return.

    try {

    if (TextIO.readUserSelectedFile() == false) {

    System.out.println("No input file selected. Exiting.");

    System.exit(1);

    }

    // Create a TreeMap to hold the data. Read the file and record data

    in the map about the words //that are found in the file.

    TreeMap words = new

    TreeMap();

    String word = readNextWord();

    while (word != null) {

    word = word.toLowerCase(); // convert word to lower case

    WordData data = words.get(word);if (data == null)

    words.put( word, new WordData(word) );

    else

    data.count++;

    word = readNextWord();

    }

    System.out.println("Number of different words found in file:

    "

    + words.size());

    System.out.println();

    if (words.size() == 0) {

    System.out.println("No words found in file.");System.out.println("Exiting without saving data.");

    System.exit(0);

    }

    // Copy the word data into an array list, and sort the list into

    order of decreasing frequency.

    ArrayList wordsByFrequency = new

    ArrayList( words.values() );

    Collections.sort( wordsByFrequency, new CountCompare() );

    // Output the data from the map and from the list.

    TextIO.writeUserSelectedFile(); // If user cancels, outputautomatically

    // goes to standard output.

    TextIO.putln(words.size() + " words found in file:\n");

    TextIO.putln("List of words in alphabetical order"

    + " (with counts in parentheses):\n");

    for ( WordData data : words.values() )

    TextIO.putln(" " + data.word + " (" + data.count + ")");

    TextIO.putln("\n\nList of words by frequency of

    occurence:\n");

    for ( WordData data : wordsByFrequency )

    TextIO.putln(" " + data.word + " (" + data.count + ")");

    System.out.println("\n\nDone.\n\n");

  • 7/31/2019 Collections(1)

    7/8

    7

    }

    catch (Exception e) {

    System.out.println("Sorry, an error has occurred.");System.out.println("Error Message: " + e.getMessage());

    e.printStackTrace();

    }

    System.exit(0); // Might be necessary, because of use of file

    dialogs.

    }

    /**

    * Read the next word from TextIO, if there is one. First, skip past

    any non-letters in the input. If *an end-of-file is encountered before

    a word is found, return null. Otherwise, read and return the *word. A

    word is defined as a sequence of letters. Also, a word can include an

    apostrophe if the *apostrophe is surrounded by letters on each side.

    @return the next word from TextIO, or null if *an end-of-file isencountered

    */

    private static String readNextWord() {

    char ch = TextIO.peek(); // Look at next character in input.

    while (ch != TextIO.EOF && ! Character.isLetter(ch)) {

    TextIO.getAnyChar(); // Read the character.

    ch = TextIO.peek(); // Look at the next character.

    }

    if (ch == TextIO.EOF) // Encountered end-of-file

    return null;

    // At this point, we know that the next character, so read a word.

    String word = ""; // This will be the word that is read.while (true) {

    word += TextIO.getAnyChar(); // Append the letter onto word.

    ch = TextIO.peek(); // Look at next character.

    if ( ch == '\'' ) {

    /**

    *The next character is an apostrophe. Read it, and if the following

    character is a letter, add both the apostrophe and the letter onto the

    word and continue reading the word. If the character after the

    apostrophe is not a letter, the word is done, so break out of the loop.

    */

    TextIO.getAnyChar(); // Read the apostrophe.

    ch = TextIO.peek(); // Look at char that follows

    //apostrophe.

    if (Character.isLetter(ch)) {word += "\'" + TextIO.getAnyChar();

    ch = TextIO.peek(); // Look at next char.

    }

    else

    break;

    }

    if ( ! Character.isLetter(ch) ) {

    // If the next character is not a letter, the word is

    // finished, so bread out of the loop.

    break;

    }

    // If we haven't broken out of the loop, next char is a

  • 7/31/2019 Collections(1)

    8/8

    8

    //letter.

    }

    return word; // Return the word that has been read.

    }

    } // end class WordCount

    can be used as a model of how to use files. That program also has a useful subroutinethat reads one word from input.

    As you read the file, you want to take each word that you encounter and add it to theconcordance along with the current line number. Keeping track of the line numbers isone of the trickiest parts of the problem. In an input file, the end of each line in the file ismarked by the newline character, \n. Every time you encounter this character, you haveto add one to the line number. WordCount.java ignores ends of lines. Because you

    need to find and count the end-of-line characters, your program cannot process the inputfile in exactly the same way as does WordCount.java. Also, you will need to detect the

    end of the file. The function TextIO.peek(), which is used to look ahead at the next

    character in the input, returns the value TextIO.EOF at end-of-file, after all the

    characters in the file have been read. Because it is so common, dont include the wordthe in your concordance. Also, do not include words that have length less than 3.

    Hints for exercise 4:

    The TreeMap can be created with the commands:TreeMap index; // Declare the variable.

    index = new TreeMap(); // Create the map

    object.

    Here is a subroutine that can print the index:/**

    * Print each entry in the index.

    */

    void printIndex() {

    for ( Map.Entry entry : index.entrySet() ) {

    String term = entry.getKey();

    TreeSet pageSet = entry.getValue();

    System.out.print( term + " " );

    for ( int page : pageSet ) {

    System.out.print( page + " " );

    }

    System.out.println();

    }}