我正在编写一个简单的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;
}
}
答案 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值低于小写字母。看起来您的索引超出范围是由大写字母引起的。