sp92
sp92

Reputation: 987

How do I display the frequency of each letter in a string?

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

Upvotes: 0

Views: 112

Answers (6)

MiraG
MiraG

Reputation: 1

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

    }
}

Upvotes: 0

forpas
forpas

Reputation: 164099

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

Upvotes: 1

Andrew
Andrew

Reputation: 49606

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

Upvotes: 6

Leniaal
Leniaal

Reputation: 1747

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

Upvotes: 1

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

Upvotes: 0

OmG
OmG

Reputation: 18838

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.

Upvotes: 1

Related Questions