0

I want my code to display each letters frequency but instead, I'm getting an ArrayIndexOutOfBoundsException. I'm having trouble spotting what I did wrong.

How can I rectify this?

Here's my code:

public static void solution(String s) {
    char[] c = s.toCharArray();
    int j = 0, i = 0, counter = 0;

    for(i = 0; i < c.length; i++) {
        counter = 0;
        for(j = 0; j < c.length; j++) {
            if(c[j] == c[i]) {
                counter++;
            }
        }
    }
    System.out.println("The letter " + c[j] + " appears " + counter + " times");
}

public static void main(String args[]) {
    String s = "abaababcdelkm";
    solution(s);
}
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
sp92
  • 873
  • 1
  • 6
  • 17
  • 1
    Apart from the `ArrayIndexOutOfBoundsException`, your code is not counting each letter's frequency, because `counter` is being reset to `0` on each outer iteration. – fps Oct 22 '18 at 17:10
  • @sp92 did you ask the same question today: https://stackoverflow.com/questions/52932509/whats-wrong-in-my-code-to-find-character-frequency, accepted one of the answers and now you post the same question with the accepted answer's code? – forpas Oct 22 '18 at 18:34
  • @OmG why did you remove the algorithm tag? the question is related to 'algorithm design' – Andrew Tobilko Oct 23 '18 at 07:27
  • @AndrewTobilko as it is not directly asking about the algorithm of the task. – OmG Oct 23 '18 at 11:37

6 Answers6

6

You are accessing c[j] outside the loop you've finished: its value is equal to c.length which isn't a correct index.

You need to move the println statement one line up and change c[j] to c[i].

I would rewrite it with Stream API:

s.chars()
 .mapToObj(c -> (char)c)
 .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
 .forEach((k, v) -> System.out.format("The letter %c appears %d times\n", k, v));
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
1

After finishing the inner loop, j is equal to the length of c. Hence, when you are calling c[j] after the outer loop, you get this error. To correct this, you can remove the print, and call another print to get the proper result. Although, you will get the repetitive print for each repeated character. If you want to prevent this, you can add your result in a hash map.

OmG
  • 18,337
  • 10
  • 57
  • 90
1
public static void solution(String s)
{

    char[] c = s.toCharArray();
    ArrayList<Character> countedChars = new ArrayList<Character>();
    int j = 0, i = 0, counter = 0;

    for (i = 0; i < c.length; i++)
    {
        if(countedChars.contains(c[i])){
            continue;
        }
        counter = 0;
        for (j = 0; j < c.length; j++)
        {
            if (c[j] == c[i])
            {
                counter++;
            }
        }
        countedChars.add(c[i]);
        System.out.println("The letter " + c[i] + " appears " + counter + " times");
    }
}

public static void main(String args[])
{
    String s = "abaababcdelkm";
    solution(s);
}

This will do a lot better, but it would be even better if you check which letters you've already counted so they won't be counted multiple times

EDIT: Added simple example of what I mean

Leniaal
  • 1,431
  • 2
  • 13
  • 23
1

If you use Collections.frequency() properly you don't have to count each char.
Just create 2 lists: the 1st containing all the chars of string and the 2nd all the distinct chars of the string:

public static void solution(String s) {
    ArrayList<Character> list = new ArrayList<Character>();
    ArrayList<Character> listDistinct = new ArrayList<Character>();

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        list.add(c);

        if (!listDistinct.contains(c))
            listDistinct.add(c);
    }

    for (char c : listDistinct) {
        int freq = Collections.frequency(list, c);
        System.out.println("The letter " + c + " appears " + freq + " times");
    }
}
forpas
  • 160,666
  • 10
  • 38
  • 76
0

You have multiple errors :

  • Your sysout should be into your first for loop
  • You search for the index 13 while printing the counter, which doesn't exists.
  • ...

I would suggest you to use this How to count frequency of characters in a string?

Here is your code :

    public static void solution(String s) {

    HashMap<Character, Integer> map = new HashMap<Character, Integer>();

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        Integer val = map.get(c);
        if (val != null) {
            map.put(c, new Integer(val + 1));
        }
        else {
           map.put(c, 1);
       }
    }
    System.out.println(map.toString());

}

public static void main(String args[]) {
    String s = "abaababcdelkm";
    solution(s);
}
0
public static void printFrequencyOfChars(String str) {
  
    if (str.length() == 1) {
        System.out.printf("(" + "%s, 1)", str);
    } else {
        Map<Character, Integer> map = new LinkedHashMap<>();
        char[] chars = str.toLowerCase().toCharArray();
        for (char c : chars) {
            map.merge(c, 1, Integer::sum);
        }
        for (Map.Entry<Character, Integer> m : map.entrySet()) {
            System.out.printf("%s%d ", m.getKey(), m.getValue());
        }

    }
}
MiraG
  • 1
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 16 '21 at 06:26