简体   繁体   中英

Word Length Frequency Counter

The code I have so far is

import java.io.*;

import static java.lang.System.*;

public class Curtis_Rodney_group8 {

    public static void main(String[] args) {
        try {
            FileReader fr = new FileReader("body.txt"); 
            BufferedReader br = new BufferedReader(fr); 

            String body;
            while ((body = br.readLine()) != null) { //read a line at a time
                out.println(body + "\n"); //disply the text untill the end of the file
            }

            br.close();
        } catch (IOException e) {
            out.println("File not found"); //if the file name is incorrect 


        }

    }
}

This code prints out the contents of the file body.txt , which is what I want.

However I now want to be able to have a word length frequency counter. For example the sentence I am a man would produce the output 2, 1, 1 (that is, two words of length 1, one word of length 2 and one word of length 3).

I am not a very experienced programmer and im also not looking for the direct answer. I am wondering how I now start the next bit of code, I think I use the body part as it is the string and I used the body = br.readLine() . I am unsure about how the next peace of code starts. Do I create a new class for the next bit of code. I hope you understand what I am asking, any help is appreciated.

Please have a look at the code below

public class FrequencyCounter {
public static void main(String args[]) {
    try {
        FileReader fr = new FileReader("body.txt");
        BufferedReader br = new BufferedReader(fr);
        Map<Integer, Integer> lengthCounter = new HashMap<Integer, Integer>();

        String body;
        while ((body = br.readLine()) != null) { // read a line at a time
            System.out.println(body);
            String[] textSplit = body.split(" ");
            for(int i=0;i<textSplit.length;i++){
                if(lengthCounter.keySet().contains(textSplit[i].length())){
                    lengthCounter.put(textSplit[i].length(),lengthCounter.get(textSplit[i].length())+1);
                } else {
                    lengthCounter.put(textSplit[i].length(),1);
                }
            }
        }

        Iterator<Integer> iter = lengthCounter.keySet().iterator();
        while(iter.hasNext()){
            int x=iter.next();
            System.out.println("Length : "+ x + " ... Freq : "+ lengthCounter.get(x));
        }
        br.close();
    } catch (IOException e) {
        System.out.println("File not found"); // if the file name is
                                                // incorrect
    }

}
}

basically the idea here is that I am using a map to store each length and the frequency of words of that length in the string.

you perform a split to get each word from the line read from text file and then check if some words of the same length have been encountered earlier. If not you add that length to the Map else you increment the previous existing value for that length as key by 1.

The output I get for following code is :

hello
my name is Abhi
I am a guy

Length : 1 ... Freq : 2
Length : 2 ... Freq : 3
Length : 3 ... Freq : 1
Length : 4 ... Freq : 2
Length : 5 ... Freq : 1

where hello my name is Abhi I am a guy

is the text read from file.

Hope that helps.

following is the solution using array. This one should be easier to understand. The only downside of this solution is that we assume the maximum length of a word in your text could be 99.

int[] lengthCounterArray = new int[100];

If you can work with a similar constraint, this solution would work for you just fine.

public class FrequencyCounter{
public static void main(String[] args) {
    try {
        FileReader fr = new FileReader("body.txt");
        BufferedReader br = new BufferedReader(fr);
        Map<Integer, Integer> lengthCounter = new HashMap<Integer, Integer>();
        int[] lengthCounterArray = new int[100]; // assuming the maximum
                                                    // word length would be
                                                    // 99 for this program
        Arrays.fill(lengthCounterArray, 0);// initializing array values to 0
        String body;
        while ((body = br.readLine()) != null) { // read a line at a time
            System.out.println(body);
            String[] textSplit = body.split(" ");
            for (int i = 0; i < textSplit.length; i++) {
                lengthCounterArray[textSplit[i].length()] += 1;
            }
        }

        for(int i =0;i<100;i++) {
            if(lengthCounterArray[i]==0)
                continue;
            else {
                System.out.println(" Length : "+i+" ... Freq : "+lengthCounterArray[i]);
            }
        }
        br.close();
    } catch (IOException e) {
        System.out.println("File not found"); // if the file name is
                                                // incorrect
    }
}

Output for this piece of code is same as the previous one

hello
my name is Abhi
I am a guy
 Length : 1 ... Freq : 2
 Length : 2 ... Freq : 3
 Length : 3 ... Freq : 1
 Length : 4 ... Freq : 2
 Length : 5 ... Freq : 1

Hope that helps.

You might want to have another class (let's call it FrequencyCounter) which takes a line of text (in a method - let's call it processLine ), splits it into words, and uses the length of each word to update a counter for the specific length. You could use a Map or a List, but it might be simpler and faster to use an array if you know the maximum possible word length (for example, an int[100] ought to be more than adequate in most cases). For example, for example, in processLine() , if you encounter the word "man", you set length to 3 and then update the counter ( this.counter[length]++ ).

In your existing code, in the loop, you would call myFrequencyCounter.processLine(body) -- myFrequencyCounter is an instance of the new class (FrequencyCounter) which you need to instantiate before the start of the while loop.

When the while loop is done, myFrequencyCounter will have have its counter field, an array of ints where the index is the length and the value is the frequency count. You can give FrequencyCounter a method that prints the frequencies and call it after the while loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM