2017-02-21 53 views
1

對於這個程序,我需要實現一個令牌迭代器,它可以從字符串中進行掃描,如果有效則存儲令牌。這看起來像一個簡單的過程,但我的代碼只返回字符串中的第一個有效令牌。我需要調用hasNext();在next()方法中的不同位置?迭代器實現只讀取字符串中的第一個標記?

這裏是我的代碼:

public class TokenIter implements Iterator<String>{ 

    //input line to be tokenized 
    private String line; 

    // the next Token, null if no next Token 
    private String nextToken; 

    //Edit 
    private Scanner scan; 

    public TokenIter(String line){ 
     this.line = line; 
    } 

    @Override 
    public boolean hasNext() { 
     //Edit 
     scan = new Scanner(line); 
      if(scan.hasNext()){ 
       nextToken = scan.next(); 
       return true; 
      } 
      scan.next(); 
      nextToken = null; 
      return false; 
    } 

    @Override 
    public String next() { 
     if(!hasNext()){ 
      throw new NoSuchElementException(); 
     } 
     else{ 
      if(nextToken.equals("true")){ 
       return nextToken; 
      } 
      if(nextToken.equals("false")){ 
       return nextToken; 
      } 
      if(nextToken.equals("or")){ 
       return nextToken; 
      } 
      if(nextToken.equals("and")){ 
       return nextToken; 
      } 
      if(nextToken.equals("not")){ 
       return nextToken; 
      } 
      if(nextToken.equals("(")){ 
       return nextToken; 
      } 
      if(nextToken.equals(")")){ 
       return nextToken; 
      } 
     } 
     return "";  
    } 

    @Override 
    public void remove() { 
     throw new UnsupportedOperationException(); 
    } 

    public static void main(String[] args){ 
     String line; 
     args = Debug.init(args); 
     if(args.length>0) 
      line = args[0]; 
     else 
      line = " not (true or error false) @# $% "; 
     System.out.println("line: [" + line + "]"); 
     TokenIter tokIt = new TokenIter(line); 
     while(tokIt.hasNext()){ 
      System.out.println("next token: [" + tokIt.next() + "]"); 
     } 
    } 

這是我正在運行的程序的輸出:

line: [ not (true or error false) @# $% ] 
next token: [not] 
next token: [not] 
next token: [not] 
next token: [not] 
next token: [not] 
next token: [not] 

這是我想要的輸出:

line: [ not (true or error false) @# $% ] 
next token: [not] 
next token: [(] 
next token: [true] 
next token: [or] 
next token: [false] 
next token: [)] 

回答

4

hasNext()方法是不正確,您每次打電話都要掃描line,以便您隨時都可以返回的第一個標記:

@Override 
    public boolean hasNext() { 
     Scanner scan = new Scanner(line); 
      if(scan.hasNext()){ 
       nextToken = scan.next(); 
       return true; 
      } 
      scan.next(); 
      nextToken = null; 
      return false; 

解決方案: scan需要使你保持hasNext()調用之間的狀態,成爲一個類變量的變量。

+0

這是有道理的。但是,行是需要標記的輸入字符串。我怎麼能跳過第一個標記到第二個方法調用中的下一個標記? – Coder123

+0

作出了改變,請參閱我的編輯。仍然收到相同的輸出 – Coder123

+0

@Lewis行'scan = new Scanner(line);'需要在構造函數中。 – Roland

2

正如已經評論的那樣,掃描器應該在構造函數中初始化。

另外TokenIter.hasNext()不是設置TokenIter.token的地方,應該只返回true或false if TokenIter.scan.hasNext()。作業應放置在TokenIter.next()

另外,Scanner類使用分隔符(默認空間),因此您應該等待捕獲"(true"作爲一個令牌。也許你想聽到話從"("開始,並將它們分成兩個令牌內部覆蓋TokenIter.next()

相關問題