Class Issues involving an Array

2019-09-06 03:52发布

问题:

I'm attempting to make an array of WordCounts, then iterate through a file line by line separating it into tokens using a split method. Then for each token, if it's in wordList, increment count, and if it's not in wordList just simply add it to the list.

Hmwk class -

public class Hmwk {        
    public static void main(String[] args) throws FileNotFoundException {
        int n=0;
        WordCount[] wordList= new WordCount[10000];
        Scanner words = new Scanner(new File("input.txt"));
        while (words.hasNextLine() && n < 10000) {
            String line = words.nextLine();
            String[] tokens = line.split("[^\\p{Alpha}]");
            for (int i = 0; i < tokens.length; i++) {
                if (tokens[i].length() > 0) {
                    WordCount word = new WordCount(tokens[i]);
                    int foundAt = search(wordList, word, n);
                    if (foundAt >= 0) {
                        word.increment();
                    } else {
                        wordList[n]=word;
                        n++;
                    }
                }
            }
        }
        //Arrays.sort(wordList);
        String alphabeticFileName = "alphabetic.txt";
        String frequencyFilename = "frequency.txt";
        PrintWriter output = new PrintWriter(alphabeticFileName);
        for (int i=0; i < n;i++) {
            output.println(wordList[i].toString());
        }
        output.close();
        //Sort on frequency somehow
        PrintWriter output2 = new PrintWriter(frequencyFilename);
        for (int i=0; i < n; i++) {
            output2.println(wordList[i].toString());
        }
        output2.close();

    }

    public static int search(WordCount[] list,WordCount word, int n) {
        int result = -1;
        int i=0;
        while (result < 0 && i < n) {
            if (word == list[i]) {
                result = i;
            }
            i++;
        }
        return result;
    }        
}

WordCount class -

class WordCount {        
    String word;
    int count;
    static boolean compareByWord;

    public WordCount(String aWord) {
        setWord(aWord);
        count = 1;
    }

    private void setWord(String theWord) {
        word = theWord;
    }

    public void increment() {
        count += 1;
    }

    public static void sortByWord() {
        compareByWord = true;
    }

    public static void sortByCount() {
        compareByWord = false;
    }

    public String toString() {
        String result = String.format("%s (%d)", word, count);
        return result;
    }        
}

It compiles and runs fine, but for some reason I'm given

Peter (1)
Piper (1)
picked (1)
a (1)
peck (1)
of (1)
pickled (1)
peppers (1)
A (1)
peck (1)
of (1)
pickled (1)
peppers (1)
Peter (1)
Piper (1)
picked (1)
If (1)
Peter (1)
Piper (1)
picked (1)
a (1)
peck (1)
of (1)
pickled (1)
peppers (1)
Where (1)
s (1)
the (1)
peck (1)
of (1)
pickled (1)
peppers (1)
that (1)
Peter (1)
Piper (1)
picked (1)

as output. Is there something wrong with my class, or my search method here? I'm lost, any and all help is much appreciated.

回答1:

Without reading through your code too carefully, it seems the problem is here:

        if (foundAt >= 0)
        {
            word.increment();
        }

Here you increment the "new" word not the one previously added. Should be something like:

        if (foundAt >= 0)
        {
            wordList[foundAt].increment();
        }


回答2:

You can change the search method's signature as follows -

public static WordCount search(WordCount[] list, String word)

You only need to pass the array and the current token (word or string), and the method should return the WordCount for the word or null if not found. That way you don't need to deal with the index, and don't need to create an instance of WordCount for current word if it's already in the array.

One, bug in your search method is word == list[i]. That's not how you check object equality, instead you should use the .equals() method for that purpose.

Now, after changing search method's signature, within the method, you would loop through the list array, compare the word inside each WordCount (i.e. list[i]) with current array element, tokens[i], and if they are equal then immediately return current WordCount (i.e. list[i]).

Then you will call the search method as follows -

WordCount wordCount = search(wordList, tokens[i]);

Then immediately check if wordCount is null. If it's null then create new instance of WordCount for the current word (i.e. tokens[i]) and put it in the array. And if it's not null then just increment it's count (wordCount.increment()).