2017-02-15 79 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(); 
     } 
    }