2016-02-12 71 views
0

我看不到數組中斷的位置,任何幫助表示讚賞。這是我的java控制檯打印出來的。拼寫檢查器建議和ArrayIndexOutOfBoundsException

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -51 
     at spellchecker.TrieNode.search(SpellChecker.java:101) 
     at spellchecker.TrieNode.suggest(SpellChecker.java:159) 
     at spellchecker.TrieNode.main(SpellChecker.java:248) 
Java Result: 1 

這是我的代碼(不是最大的),可以使用建議。 要自己運行它,請創建一個文本文件,其中包含一個名爲「dictionary.txt」的字典單詞列表,並將輸入文件的名稱輸入到鍵盤掃描器。在應該執行此操作的suggest()方法內部註釋掉代碼,通過在單詞中每個相鄰的 字符之間添加一個 空間,將該單詞分割爲一對單詞。應該注意的是,如果 兩個 都是在詞典中找到的話,那麼將只產生一個建議 。如果你有一個例子或者可以指導我去哪裏了這一建議,例如單詞:missspelling應該建議[拼寫錯誤,錯過拼寫]

package spellchecker; 

import java.io.*; 
import java.util.*; 

//Name of SpellChecker file that contains Trie data structure, lexicon dictionary 
//file readers, and suggestable words for misspelled words 
class SpellChecker { 
} 

    class TrieNode { 

    //Trie variables 
    char letter; 
    TrieNode[] links; 
    boolean fullWord; 

    /** 
    * Constructs a Trie 
    * 
    * @param letter Empty char in Trie root 
    * @param fullWord Double pointer indicates complete word 
    */ 
    TrieNode(char letter, boolean fullWord) { 
     this.letter = letter; 
     links = new TrieNode[26]; 
     this.fullWord = fullWord; 
    } 

    /** 
    * Creates a Trie 
    * 
    * @return Trie with implementations 
    */ 
    static TrieNode createTree() 
    { 
     return(new TrieNode(' ', false)); 
    } 

    /** 
    * Adds a word to the Trie 
    * 
    * @param root Trie to edit 
    * @param word Word to add to the Trie 
    */ 
    static void insertWord(TrieNode root, String word) 
    { 
     int offset = 97; 
     int l = word.length(); 
     char[] letters = word.toLowerCase.toCharArray(); 
     TrieNode curNode = root; 
     for (int i = 0; i < l; i++) 
     { 
      if (curNode.links[letters[i] - offset] == null) 
       curNode.links[letters[i] - offset] = new TrieNode(letters[i],i == l - 1 ? true : false); 
      curNode = curNode.links[letters[i] - offset]; 
     } 
    } 

    /** 
    * Searches the Trie for the word in parameters and returns if the word is 
    * found or not 
    * 
    * @param root Starting Trie root 
    * @param word Word being searched for 
    * @return True if word is found, false if not 
    */ 
    static boolean search(TrieNode root, String word) 
    { 
     char[] letters = word.toLowerCase.toCharArray(); 
     int l = letters.length; 
     int offset = 97; 
     TrieNode curNode = root; 
     int i; 
     for (i = 0; i < l; i++) 
     { 
      if (curNode == null) 
       return false; 
      //Error 101 here 
      if (letters[i] < 97) 
       curNode = curNode.links[letters[i] - offset]; 
     } 
     if (i == l && curNode == null) 
      return false; 
     if (curNode != null && !curNode.fullWord) 
      return false; 
     return true; 
    } 

    /** 
    * This method removes the punctuation and capitalization from a string. 
    * 
    * @param sentence The sentence that needs editing. 
    * @return The edited sentence. 
    */ 
    public static String removePunctuation(String sentence) { 
     String newSentence; // the new sentence 
     //remove evil punctuation and convert the whole line to lowercase 
     newSentence = sentence.toLowerCase().replaceAll("[^a-zA-Z" 
              +"\\s]", "").replaceAll("\\s+", " "); 
     return newSentence; 
    } 

    /** 
    * Returns possible suggestions for misspelled word 
    * 
    * @param tree The Trie that will be checked 
    * @param word The word in trie that is checked 
    */ 
    public static void suggest(TrieNode tree, String word) { 
     Set<String> result = new HashSet<>(); 
     System.out.println("Suggestions: "); 
     // Remove a character 
     for (int i = 0; i < word.length(); ++i) 
      result.add(word.substring(0, i) + word.substring(i + 1)); 
     // Swap two consecutive characters 
     for (int i = 0; i < word.length() - 1; ++i) 
      result.add(word.substring(0, i) + word.substring(i + 1, i + 2) + word.substring(i, i + 1) 
        + word.substring(i + 2)); 
     // Replace a character with other 
     for (int i = 0; i < word.length(); ++i) 
      for (char c = 'a'; c <= 'z'; ++c) 
       result.add(word.substring(0, i) + String.valueOf(c) + word.substring(i + 1)); 
     // Add a new character 
     for (int i = 0; i <= word.length(); ++i) 
      for (char c = 'a'; c <= 'z'; ++c) 
       result.add(word.substring(0, i) + String.valueOf(c) + word.substring(i)); 
     //FIXTHISCODE to swap adjacent chars and check if words 
    //split are both words and check if they are in dictionary 
    for (int i = 0; i < word.length(); i++) { 
     String working = word.substring(0, i); 
     working += word.charAt(i + 1); 
     working += word.charAt(i); 
     working = working.concat(word.substring((i + 2))); 
     if (search(tree, working)) { 
      result.add(working); 
     } 
    } 
     ArrayList<String> res = new ArrayList<>(result); 
     int j = 0; 
     for (int i = 0; i < result.size() - 1; i++) 
      //Error 159 here 
      if (search(tree, res.get(i))) { 
       if (j == 0) 
        //System.out.println("Suggestions: " + "\n" + "["); 
        System.out.print("["); 
       System.out.print(res.get(i) + ","); 
       System.out.print(""); 
       j++; 
      } 
     System.out.print("]" + "\n"); 
    } 

    /** 
    * Reads in lexicon and input file, suggests new words 
    * 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException 
    { 
     TrieNode tree = createTree(); 

     //long build1 = System.currentTimeMillis(); 

     File f = new File("dictionary.txt"); 

     FileReader fR = new FileReader(f); 

     BufferedReader br = new BufferedReader(fR); 

     String ele; 

     while ((ele = br.readLine()) != null) 
      insertWord(tree, ele); 

     System.out.println("Done reading dictionary."); 

     //long build2 = System.currentTimeMillis(); 

     //System.out.println("Time to build data structure is: " + (build2 - build1)); 

     Scanner input = new Scanner(System.in); 

     System.out.println("Enter the name of your (input.txt) file."); 

     String str = input.nextLine(); 

     File file = new File(str); 

     /** 
     * Inner Lexicon class 
     */ 
     class Lexicon { 

      /** 
      * This method checks to see if the word being passed in through 
      * parameter is a word that is spelled correctly and in the Lexicon 
      * 
      * @param word Word spelling that you want to check 
      * @return True if word is found, False if not 
      */ 
      public boolean isWord(String word) { 
       if (search(tree, word)) 
        return true; 
       else { 
        return false; 
       } 
      } 
     } 

     Lexicon lexicon = new Lexicon(); 

     Scanner fileScanner = new Scanner(file); 

     String line = ""; 

     while (fileScanner.hasNext()) { 
      line = fileScanner.nextLine(); 

      Scanner fileScan = new Scanner(line); 

      System.out.println(line); 

      //This reads the input file word by word 
      while(fileScan.hasNext()) { 
       String s = fileScan.next(); 

      if (lexicon.isWord(removePunctuation(s)) == false) { 
       System.out.println("\n" + s + " is not spelled correctly!"); 
       //Error 248 here 
       suggest(tree, s); 
      } 
      } 
     } 
    } 
} 
+0

,你不能只是把在101獨立 –

+0

@SamOrzco行解決這個問題,我不這麼認爲,因爲行101:CURNODE = curNode.links [字母[I] - 偏移] ;檢查Trie中的鏈接,並在for循環中? – KrakenJaws

+0

哪一行是101行?你可能會對此發表評論嗎? –

回答

1

由於offset設置爲97,和違規行爲curNode.links[letters[i] - offset]並且錯誤表示您嘗試訪問的索引是-51,則letters[i]的ASCII值爲46,即週期字符的值。這導致我相信你的輸入文件會在其中使用句點,這將會被你的搜索功能不適當地處理。爲了解決這個問題,我建議在curNode = curNode.links[letters[i] - offset];之前,這將導致你的搜索功能,忽略週期和符號,將程序崩潰的放線

if (letters[i] < 97) continue; 

。 編輯 -21意味着你得到一個大寫字母'L'而你的程序不能處理大寫字母。你可以通過改變char[] letters = word.toCharArray();char[] letters = word.toLowerCase().toCharArray();

+0

我已經這樣做了,只是拋出另一個ArrayIndexOutOfBoundsException:-21 – KrakenJaws

+0

我編輯我的帖子。它現在應該工作。 –

+0

好吧,似乎設置char []字母toLowerCase第一次幫助,如果(字母[我] <97)似乎打破我的輸出文本代碼,並說每個單詞拼寫錯誤。 – KrakenJaws