使用2d数组的OutOfBounds异常

时间:2017-02-15 20:06:24

标签: java arrays multidimensional-array

我正在创建一个程序,查找文本行中是否有一对2个字母,例如,如果输入“AA”,我会将1添加到字母[0] [0]。当我尝试输入“aabbcc”时,我收到此错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 32
        at Freq.processLine(Freq.java:25)
        at Freq.main(Freq.java:12)

当我输入“AABBCC”时,我收到此错误:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
        at java.lang.String.charAt(String.java:658)
        at Freq.processLine(Freq.java:23)
        at Freq.main(Freq.java:12)

我不确定为什么我会收到这些错误。任何帮助将不胜感激。这是我的代码:

import java.util.Scanner;

public class Freq{
    private static final int ROWS = 26;
    private static final int COLS = 26;
    private static int[] [] alphabet = new int[ROWS][COLS];
    public static void main(String[] args) {
        String line;
        Scanner userInput = new Scanner(System.in);
        while(userInput.hasNextLine()) {
            line = userInput.nextLine();
            processLine(line);

    }

}
public static void processLine(String line) {
    line.toUpperCase();
    for(int i = 0; i < alphabet.length; i++) {
        for(int j = 0; j < alphabet[i].length; j++) {
            for (int a = 0; a < line.length(); a++) {
                char firstLetter = line.charAt(a);
                char secondLetter = line.charAt(a + 1);
                if (firstLetter == secondLetter) {
                    alphabet[firstLetter - 65][secondLetter - 65] = alphabet[firstLetter - 65][secondLetter - 65] + 1;
                }
            }
        }
    }
for (int b = 0; b < alphabet.length; b++) {
    for (int c = 0; c < alphabet[b].length; c++){
        System.out.print(alphabet[b][c] + " ");
        System.out.println();
    }
}
}
}

2 个答案:

答案 0 :(得分:3)

第一个问题在这里:

line.toUpperCase();

返回一个转换为大写的字符串,并保留原始字符串不变。这很清楚,因为Java中的字符串是不可变的。

所以你需要做的是:

line = line.toUpperCase();

另一个问题是line.charAt(a + 1);超出了a = line.length() - 1

答案 1 :(得分:1)

即使纠正了Frank Puffer提到的错误,您的代码仍然无法获得所需的结果,因为当达到token ws { \s* | <slash-star-comment>* | <dashes-comment>* } token slash-star-comment { \s* '/*!' .*? '!*/' \s* } token dashes-comment { \s* '--' \N* \s* } 的最后一个字符时,前两个循环不会中断。这样,代码经过字符串26 * 26次。所以,如果字符串包含一个&#34; aa&#34;对,而不是得到&#34; 1&#34;的结果,你将得到&#34; 676&#34;的结果。

由于您可以在没有前两个循环的情况下填充数组,因此您甚至不需要实现相应的break语句 - 您可以简单地从代码中取出前两个循环。此外,如果您希望结果以矩阵格式显示,则由最后四行代码实现的字符显示将不正确。

此外,根据您如何定义什么算作一对相同的字符,如果相同的字符串包含任何字符串,您将拥有不同数量的相同字符对。

第一种情况: 如果允许使用同一个字符来构造具有其他相同相邻字符的不同对,则将得到一个结果。因此,如果字符串包含&#34; aaa&#34;,则代码将计算两对&#34; a&#34; - 由第一个和第二个&#34; a&#34;以及第二个和第三个&#34; a&#34;代表。

第二种情况: 如果不允许使用同一个字符来构造具有其他相同相邻字符的不同对,则会产生另一个结果。因此,如果字符串包含&#34; aaa&#34;,则代码将只计算一对&#34; a&#34; - 由第一个和第二个代表&#34; a&#34;。

因此,假设您的代码正确表示您的预期结果,您的目标是按照第一个方案获得结果。 无论如何,以下是两种方案的方法,包括以矩阵格式显示数组的方法。

第一种情况:

String line

第二种情况:

public static void processLine(String line) {
        line = line.toUpperCase();
        for (int a = 0; a < line.length() - 1; a++) {
            char firstLetter = line.charAt(a);
            char secondLetter = line.charAt(a + 1);
            if (firstLetter == secondLetter) {
                alphabet[firstLetter - 65][secondLetter - 65] = alphabet[firstLetter - 65][secondLetter - 65] + 1;
            }
        }
        display(alphabet);
    }

以矩阵格式显示结果:

public static void processLine(String line) {
        line = line.toUpperCase();
        int a = 0;
        while (a < line.length() - 1) {
            char firstLetter = line.charAt(a);
            char secondLetter = line.charAt(a + 1);
            if (firstLetter == secondLetter) {
                alphabet[firstLetter - 65][secondLetter - 65] = alphabet[firstLetter - 65][secondLetter - 65] + 1;
                a = a + 2;
            } else {
                a++;
            }
        }
        display(alphabet);
    }