0

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? }

Sarah
  • 45
  • 12
  • 1
    An "easy"/"convenient" way could be to create a hashmap with keys for all letters of the alphabet, and store the counters as values in that same hashmap. – fvu Aug 25 '16 at 11:48
  • You could do a 2d Array/List maybe? I'd say go for a `List ` if it were in C# but I hope it makes sense :) – uTeisT Aug 25 '16 at 11:49
  • Possible duplicate of [Java: How do I count the number of occurrences of a char in a String?](http://stackoverflow.com/questions/275944/java-how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string) – xenteros Aug 25 '16 at 12:00

3 Answers3

3

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

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    It never stops to amaze me how many ordering and arranging tricks were done in the ASCII table to simplify common operations... – fvu Aug 25 '16 at 11:59
  • Unfortunately, if you use such a solution, no matter how elegant it may seem at a first glance, you are in big reworking problems as soon as you think about internationalization. (OK, the OPs question has the same problem, but he would be able to just update his definition array.) Or in other words: it never stops to amaze me, that in 2016 there's still people who rely on numeric trickery with the ASCII table... – mtj Aug 25 '16 at 12:49
  • @mtj you can use `Character.toUpperCase` and an `int[65536]` or larger for code points. Not a dramatic change. It's not clear whether the OP would want to map characters which look like `a` to `a` for example. Even toUpperCase has problems as you can get two characters from one. – Peter Lawrey Aug 25 '16 at 13:15
1

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

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
1

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();
    }

}

}

scrineym
  • 759
  • 1
  • 6
  • 28