2017-02-15 86 views
1

我正在用于查找是否存在一行文本中的信对2个字母,例如,如果“AA”被输入时,我会加1字母的程序[0] [0]。当我试着输入“为aabbcc”我得到这个错误:OutOfBounds异常与2D阵列

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

回答

3

第一个问题就在这里:

line.toUpperCase(); 

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

所以,你需要做的是:

line = line.toUpperCase(); 

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

+0

保佑你的灵魂 – Coder117

1

即使修正由弗兰克·河豚提到的错误后,你的代码仍然不会因为到达的String line的最后一个字符,当你第一次两个循环不打破得到期望的结果。通过这种方式,代码通过字符串26 * 26次。所以,如果字符串包含一个“aa”对,而不是得到“1”的结果,您将得到“676”的结果。

既然你能填充数组没有前两个循环,你甚至都不需要实施相应的break语句 - 你可以简单地采取先两个循环出来的代码。另外,如果希望以矩阵格式显示结果,则由最后四行代码实现的字符显示将不正确。

此外,取决于你如何定义为一对相同的字符才算数,你将有不同数量的对相同字符的同一字符串,如果它包含任何。

第一种情况: 如果您允许同一个字符用于与其他相同的相邻字符构造不同的字符对,您将得到一个结果。因此,如果字符串中包含“AAA”,代码将计数2双“一” - 由第一和第二个“a”,以及由所述第二和第三的“a”表示。

第二种情况: 你将有相当另一个结果是,如果你不允许之一,用于对不同与其他相同的邻近字符的建设相同的字符。因此,如果字符串包含“aaa”,则代码将只计算一对“a” - 由第一个和第二个“a”表示。

因此,假设你的代码正确代表您预期的结果,你的目标是有结果按照第一个方案。 无论如何,下面是用于这两种情况的方法中,包括显示以矩阵形式的阵列的方法。

第一种方案:

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

显示结果以矩阵形式:

public static void display(int[][] table) { 
     for (int i = 0; i < table.length; i++) { 
      for (int j = 0; j < table[i].length; j++) { 
       System.out.print(alphabet[i][j]); 
      } 
      System.out.println(); 
     } 
    }