Sarah
Sarah

Reputation: 45

Count occurrence of alphabet characters from txt file

I am trying to count the occurrence of every letter of the alphabet when reading from a txt file. So far my code just counts the letter a - successfully tho.

int counter = 0;
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        int ch;
        for (char a : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) {

            char toSearch = a;
            counter = 0;
            while ((ch = reader.read()) != -1) {
                if (a == Character.toUpperCase((char) ch)) {
                    counter++;
                }
            }
            System.out.println(toSearch + " occurs " + counter);

        }

How do I make it work, that all letters are counted for? }

Upvotes: 0

Views: 1722

Answers (3)

scrineym
scrineym

Reputation: 759

Your problem is in the buffered reader. Every time you call reader.read() it moves to the next character, so when your loop ends it has read to the end of the file. At the end of your for loop you need to reset the buffered reader to point to the start of the file again. In order to do this you need to create a new buffered reader object, in your case if you simply move the line BufferedReader reader = new BufferedReader(new FileReader(file)) to after the for loop your code will work.

public class Test {
public static void main(String [] args) {

    File file = new File("test.txt");
    int counter = 0;
    try {

        int ch;
        for (char a : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            char toSearch = a;
            counter = 0;

            while ((ch = reader.read()) != -1) {
                if (a == Character.toUpperCase((char) ch)) {
                    counter++;
                }
            }
            System.out.println(toSearch + " occurs " + counter);

        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

Upvotes: 1

TheLostMind
TheLostMind

Reputation: 36304

Brute Force logic :

  • Files.readAllLines() / Loop = FileReader + BufferedReader to read lines from file.

  • For each line read, convert it to lowercase (we don't wan to count A and a seperately), get the char array. Create a Map

  • Iterate over the char array and for each char, check if it is already present in the map. If it is not present, add it to the map with value 1. If key is present, get the value, add 1 to it and put the value back

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533520

The problem you have is that you are reading the entire file compares the first letter and by the time you come to the second letter there is no file left.

Instead of using a nested loop, you can increment an element in array of values, one for each letter. e.g.

int[] letterCount = new int[27];
for (int ch; (ch = reader.read()) != -1; ) {
    if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
        letterCount[ch % 32]++; // update the counter for the letter.
}

In this case letterCount[1] will be the count for a or A and letterCount[2] will be the count for b or B

Upvotes: 3

Related Questions