2013-02-13 32 views
-2

這是一個定製的解析器,因爲我真的不喜歡默認的java.util.Scanner的工作方式。解析器缺少最後一個單詞 - Java

我的問題是,當我使用新的解析器(「Parsed phrase here」)或函數reloadBuffer(「Parsed phrase here」)創建解析器時,它會錯過輸入的最後一個單詞。我試圖儘可能使這段代碼儘可能易讀,但它仍然非常密集,對此抱歉。哦,如果這個問題得到解決,請隨時使用它。

import java.util.*; 

public class Parser 
{ 

    public static char letters[] = new char[]{'q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'}; 
    public static char numbers[] = new char[]{'0','1','2','3','4','5','6','7','8','9'}; 

    public ArrayList<String> words; 
    public String buffer; 
    public int wordIndex; 
    /** 
    * Assembles an empty parser. 
    */ 
    public Parser() 
    { 
     words = new ArrayList<String>(); 
     buffer = ""; 
     wordIndex = 0; 
    } 
    /** 
    * Assembles the Parser with given String as input. Uses reloadBuffer(); 
    * @see reloadBuffer 
    */ 
    public Parser(String input) 
    { 
     words = new ArrayList<String>(); 
     reloadBuffer(input); 
    } 
    /** 
    * Parses each word/set of chars into the array. Must be called before any retreiving of words can be done. 
    * This is basically the core function of the class. Be very careful if you edit this part. 
    */ 
    public void parseBuffer(){ 
     String input = buffer; 
     while(input.length()>=1) 
     { 
      input = trimToSelectedChars(input); 
      words.add(removeFirstSet(input)[0]); 
      input = removeFirstSet(input)[1]; 
     } 
    } 
    /** 
    * Resets the array with given String as input. Used in the primary constructor. Uses parseBuffer(); 
    * @see parseBuffer() 
    */ 
    public void reloadBuffer(String input){ 
     buffer = input; 
     wordIndex = 0; 
     parseBuffer(); 
    } 

    /** 
    * @return the next word parsed from the string, based upon the value of wordIndex. 
    */ 
    public String next(){ 
     wordIndex++; 
     if (wordIndex<= words.size()+1){ 
      try {return words.get(wordIndex-1); 
      } catch(Exception ex) { 
       System.err.println("Error: reached end of list. Resetting index to 0."); 
       resetIndex(); 
      } 
     } 
     return ""; 
    } 

    //Notice that when using wordAt(), it leaves the index where you selected, and it does not revert to where it was before. 
    /** 
    * @return the word at indicated index, much like the charAt() function, using the next() function. Also sets wordIndex to input index. 
    * @see String 
    * @see next() 
    */ 
    public String wordAt(int index){ 
     wordIndex = index; 
     return next(); 
    } 

    /** 
    * @return the first word parsed from the input. 
    * @see String 
    */ 
    public String firstWord() 

    { 
     return wordAt(0); 
    } 

    /** 
    *Be careful in using lastWord() as it sets the wordIndex to the last value which will return a String 
    *@return the last parsed word from the input. 
    */ 
    public String lastWord(){ 
     return wordAt(words.size()-1); 
    } 

    /** 
    * Resets the wordIndex to 0, the beginning. 
    */ 
    public void resetIndex(){wordIndex = 0;} 

    /** 
    * return whether or not there is another word in the parser list. 
    */ 
    public boolean hasNext(){ 
     return (wordIndex<words.size()); 
    } 
    //internal methods here. 
    private String[] removeFirstSet(String input) 
    //removes the first set of adjecent letters from a string, and returns it. 
    { 
     String[] words = new String[2]; 
     int index = 0; 
     if(input.length()<1) words[0] = ""; 
     while(index<input.length()){ 
      //this loop to retrieve the first word. 
      if(isLetter(input.charAt(index))||isNumber(input.charAt(index))){ 
       index++; //if the first char is a letter, move on to the next one. 
      } 
      else{ 
       words[0]=input.substring(0,index); 
       words[1]=input.substring(index); 
       return words; 
      } 
     } 
     return new String[]{"",""}; 
    } 

    private String trimToSelectedChars(String input) 
    //trims anything that is not a letter from the front of a String. 
    { 
     input = input.trim(); 
     while(input.length()>0){ 
      //this loop to clear up junk before the input. 
      if(isLetter(input.charAt(0))||isNumber(input.charAt(0))){ 
       break; //if the first char is a letter or a number, break the loop 
      } 
      else input=input.substring(1);// else cut the first char off the string. 
     } 
     return input; 
    } 

    private boolean isLetter(char c) 
    //returns whether or not the indicated char is an alphabetical letter. 
    { 
     for(int i = 0; i<letters.length; i++){ 
      if(letters[i]==c)return true; 
     } 
     return(false); 
    } 

    private boolean isNumber(char c) 
    //returns whether or not the indicated char is a number. 
    { 
     for(int i = 0; i<numbers.length; i++){ 
      if(numbers[i]==c)return true; 
     } 
     return(false); 
    } 
} 
+1

一,學會正確使用掃描儀,這是一個非常標準的課程,我懷疑你的問題是由於圖書館的設計不佳造成的。 – djechlin 2013-02-13 04:38:46

+1

這對我來說看起來不太好。首先,必須有至少幾十個選項用於將字符串解析爲單詞列表。此外,你正在創建一個類似集合的類,它既不是'Collection'也不''Iterable',這嚴重阻礙了它的用處。除非在這裏埋藏一些真正獨特而有用的東西,否則它看起來像是未來的維護頭痛,沒有任何實際益處。 – 2013-02-13 04:38:59

+1

二,「調試我的代碼」太本地化了,並不是一個合法的問題。 – djechlin 2013-02-13 04:39:11

回答

0

用下面的

private String[] removeFirstSet(String input) 
    //removes the first set of adjecent letters from a string, and returns it. 
    { 
     String[] words = new String[2]; 
     int index = 0; 
     if(input.length()<1) words[0] = ""; 
     while(index<input.length()){ 
      //this loop to retrieve the first word. 
      if(isLetter(input.charAt(index))||isNumber(input.charAt(index))){ 
       index++; //if the first char is a letter, move on to the next one. 
      } 
      else{ 
       words[0]=input.substring(0,index); 
       words[1]=input.substring(index); 
       return words; 
      } 
     } 
     if(index==input.length()){ 
      words[0]=input.substring(0,index); 
      words[1]=input.substring(index); 
      return words; 
     } 
     return new String[]{"",""}; 
    } 

希望這將解決你的問題,用替換法removeFirstSet。