Java:数组索引超出界限异常2

时间:2014-07-27 21:19:29

标签: java indexoutofboundsexception

我正在编写一个简单的Java程序,要求用户输入一个字符串,然后计算并显示字母表中每个字母出现在该字符串中的次数。当我编译时,我收到此错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -25
at StringLetters.countLetters(StringLetters.java:43)
at StringLetters.main(StringLetters.java:23)

我已经研究过类似于我的问题的其他解决方案,但没有一个能够帮助我。有没有人有任何想法?谢谢。

    import java.util.Scanner;

    public class StringLetters
    { 
    public static void main(String[]args) 
    { 
        Scanner scan = new Scanner(System.in);
        System.out.println("Please enter a string of words.");
        String s = scan.nextLine();

        int[] counts = countLetters(s.toUpperCase());

        for(int i = 0; i < counts.length; i++)
        {
            if (counts[i] != 0) 
            {
                System.out.println((char)('a' + i) + " appears " + counts[i] + ((counts[i] == 1) ? "time" : " times"));
            }
        }
    }


    public static int[] countLetters(String s)
    {
        int[] counts = new int[26];

        for (int i = 0; i < s.length(); i++)
        {
            if(Character.isLetter(s.charAt(i)))
            {
                counts[s.charAt(i) - 'a']++;
            }
        }

        return counts;
    }

}

5 个答案:

答案 0 :(得分:2)

嗯,显然counts[s.charAt(i) - 'a']中的索引超过25.看起来你假设你的所有输入都是小写字母,即使你传递给你的countLetters方法一个大写字符串(countLetters(s.toUpperCase());)。

您应该将其更改为counts[s.charAt(i) - 'A']。当然,这只适用于大写字母,但那是你目前传递给这种方法的内容。

答案 1 :(得分:2)

在您传递给计数方法的字符串中,您的字母不是小写的英文字母,会破坏您的代码。

事实上,由于您正在调用s.toUpperCase(),所以它们都不是小写的,而您似乎打算致电s.toLowerCase()。此外,您需要过滤掉标点符号和任何非字母字符。您已在此处执行此操作:if (Character.isLetter(s.charAt(i)))

所以只需将s.toUpperCase()更改为s.toLowerCase()即可。

答案 2 :(得分:1)

首先,你的问题 - 你如何处理大写字母?

显然,在您的用例中,您执行countLetters(s.toUpperCase()),然后执行- 'a'。这给出了非常奇怪的结果:

(int)'A' - (int)'a' = -25
(int)'Z' - (int)'a' = -7

更简单的方法是使用Map。使用Java 8:

    final Map<Character, Integer> counts = input.toUpperCase().chars().
            collect(HashMap::new, (m, l) -> m.merge((char) l, 1, Integer::sum), Map::putAll);

答案 3 :(得分:1)

isLetter在很多情况下都可以返回true(看看它的javadoc)。特别是对于大写字符(peter&gt; petrov是对的,你可能不想转换为大写字母......)

我建议实施更基本的测试:

        Char c = s.charAt(i);
        if('a' <= c && c <= 'z')
        {
            counts[c - 'a']++;
        }
        else if('A' <= c && c <= 'Z')
        {
            counts[c - 'A']++;
        }

答案 4 :(得分:0)

你如何解释大写字母?似乎很适合HashMap。大写字母的ASCII值低于小写字母。看起来您的索引超出范围是由大写字母引起的。