2011-11-02 88 views
0

我遇到了前綴表達式求值程序的錯誤。我的前綴表達式評估程序遇到問題

,我得到的,當我嘗試運行它的錯誤是

Expression (+ (- 6) (* 2 3 4) (/ (+ 3) (- 2 3 1))) 
Expression in thread "main" java.lang.NumberFormatException: For input string: "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))" 
at sun.misc.FloatingDecimal.readJavaFormatException: For input string "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))" 
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source) 

//code starts here 
     import java.util.*; 

     public class SimpleLispExpressionEvaluator { 

     // Current input Lisp expression 
     private String inputExpr; 


     // Main stack & temp stack, see algorithm in evaluate() 
     private Stack<Object> expressionStack; 
     private Stack<Double> tempStack; 


     // default constructor 
     // set inputExpr to "" 
     // create stack objects 
     public SimpleLispExpressionEvaluator() 
     { 
     inputExpr = ""; 
     expressionStack = new Stack<Object>(); 
     tempStack = new Stack<Double>(); 
     } 



     // default constructor 
     // set inputExpr to inputExpression 
     // create stack objects 
     public SimpleLispExpressionEvaluator(String inputExpression) 
     { 
      inputExpr = inputExpression; 
      expressionStack = new Stack<Object>(); 
      tempStack = new Stack<Double>(); 
      } 


     // set inputExpr to inputExpression 
     // clear stack objects 
     public void reset(String inputExpression) 
     { 
     inputExpr = inputExpression; 
     Stack<Object> expressionStack = new Stack<Object>(); 
     Stack<Double> tempstack = new Stack<Double>(); 

     } 

     private boolean checkifNumber() { 
      return false; 
     } 


     // This function evaluate current operator with its operands 
     // See complete algorithm in evaluate() 
     // 
     // Main Steps: 
     //  Pop operands from expressionStack and push them onto 
     //   tempStack until you find an operator 
     //  Apply the operator to the operands on tempStack 
     //   Push the result into expressionStack 
     // 

     `private double add() { 
      double op1 = tempStack.pop(); 
      double op2 = tempStack.pop(); 
      double temp = op1 + op2; 
      return temp; 
     }` 

     private double multiply() { 
      double op1 = tempStack.pop(); 
      double op2 = tempStack.pop(); 
      double temp = op1 * op2; 
      return temp; 
     } 

     private double subtract() { 
      if (tempStack.size() == 1) { 
          double temp = -tempStack.pop(); 
         return temp; 
       } else { 

      double op1 = tempStack.pop(); 
      double op2 = tempStack.pop(); 
      double temp = op1 - op2; 
      return temp; 
     } 
     } 

     private double divide() { 
      if (tempStack.size() == 1) { 
          double temp = 1/tempStack.pop(); 
       return temp; 
          } else if (tempStack.pop() == 0 || tempStack.pop() == null) { 
       throw new IndexOutOfBoundsException(); } else { 
        double op1 = tempStack.pop(); 
         double op2 = tempStack.pop(); 
        double temp = op1 - op2; 
        return temp; 
       } 
     } 








     private void evaluateCurrentOperation() 
     { 






     while(expressionStack.peek().getClass().getName().equals("java.lang.Double")) { 
       tempStack.push((Double)expressionStack.pop()); 
      } 
      Character operator = (Character)expressionStack.pop(); 
      Double result = null; 
      switch(operator) { 
       case '+': 
        result = add(); 
        break; 
       case '*': 
        result = multiply(); 
        break; 
       case '-': 
        result = subtract(); 
        break; 
       case '/': 
        result = divide(); 
        break; 
      } 
      expressionStack.push(result); 
        } 






     /** 
     * This function evaluates Lisp expression in inputExpr 
     * It return result of the expression 
     * 
     * The algorithm: 
     * 
     * Step 1 Scan the tokens in the expression string. 
     * Step 2  If you see an operand, push operand object onto the expressionStack 
     * Step 3   If you see "(", next token should be an operator 
     * Step 4  If you see an operator, push operator object onto the expressionStack 
     * Step 5  If you see ")" // steps in evaluateCurrentOperation() : 
     * Step 6   Pop operands and push them onto tempStack 
     *     until you find an operator 
     * Step 7   Apply the operator to the operands on tempStack 
     * Step 8   Push the result into expressionStack 
     * Step 9 If you run out of tokens, the value on the top of expressionStack is 
     *   is the result of the expression. 
     */ 
     public double evaluate() 
     { 
     // only outline is given... 
     // you need to add statements 
     // you may delete or modify any statements in this method 

      // use scanner to tokenize inputExpr 
      Scanner inputExprScanner = new Scanner(inputExpr); 

      // Use zero or more white space as delimiter, 
      // which breaks the string into single character tokens 
      inputExprScanner = inputExprScanner.useDelimiter("\\s*"); 

      // Step 1: Scan the tokens in the string. 
      while (inputExprScanner.hasNext()) 
      { 

       // Step 2: If you see an operand, push operand object onto the expressionStack 
       if (inputExprScanner.hasNextInt()) 
       { 
        // This force scanner to grab all of the digits 
        // Otherwise, it will just get one char 
        String dataString = inputExprScanner.findInLine("\\d+"); 
      expressionStack.push(new Double(dataString)); 

      // more ... 
       } 
       else 
       { 
      // Get next token, only one char in string token 
        String aToken = inputExprScanner.next(); 
        char item = aToken.charAt(0); 
        String nextToken; 
      char nextItem; 
        switch (item) 
        { 
        // Step 3: If you see "(", next token should be an operator 
       case '(': 
        nextToken = inputExprScanner.next(); 
        nextItem = nextToken.charAt(0); 
        // Step 4: If you see an operator, push operator object onto the expressionStack 
       if (nextItem == '+') { 
           expressionStack.push(nextItem); 
          } else if (nextItem == '-') { 
           expressionStack.push(nextItem); 
          } else if (nextItem == '*') { 
           expressionStack.push(nextItem); 
          } else { 
           expressionStack.push(nextItem); 
          } 



       break; 
        // Step 5: If you see ")" // steps 6,7,8 in evaluateCurrentOperation() 
       case ')': 

        try { 
        evaluateCurrentOperation(); 
       } catch (EmptyStackException e) { 
        break; 
       } 

       break; 
         default: // error 
          throw new RuntimeException(item + " is not a legal expression operator"); 
        } // end switch 
       } // end else 
      } // end while 

      // Step 9: If you run out of tokens, the value on the top of expressionStack is 
      //   is the result of the expression. 
      // 
      //   return result 
      double result = new Double(inputExpr); 
     return result; 
     } 


     // This static method is used by main() only 
     private static void evaluateExprt(String s, SimpleLispExpressionEvaluator expr) 
     { 
      Double result; 
      System.out.println("Expression " + s); 
     expr.reset(s); 
      result = expr.evaluate(); 
      System.out.printf("Result %.2f\n", result); 
      System.out.println("-----------------------------"); 
     } 

     // simple tests 
     public static void main (String args[]) 
     { 
      SimpleLispExpressionEvaluator expr= new SimpleLispExpressionEvaluator(); 
      String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))"; 
      String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))"; 
      String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1)))"; 
      String test4 = "(+ (/2))"; 
      String test5 = "(+ (/2 3 0))"; 
      String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1))))"; 
     evaluateExprt(test1, expr); 
     evaluateExprt(test2, expr); 
     evaluateExprt(test3, expr); 
     evaluateExprt(test4, expr); 
     evaluateExprt(test5, expr); 
     evaluateExprt(test6, expr); 
     } } 

回答

1

步驟的evaluate 9是沒有做什麼評論說:

 // Step 9: If you run out of tokens, the value on the top of expressionStack is 
     //   is the result of the expression. 
     // 
     //   return result 
     double result = new Double(inputExpr); 

它試圖將整個輸入字符串轉換爲雙精度型,而不是檢索表達式堆棧的頂部。它應該像

 double result = (Double)expressionStack.pop(); 

也提防的是,運營商,如實施,不接受3個或多個參數 - (* 2 3 4)不應該工作。

+0

在收到您的建議後,我在java.util.Stack.peek中的線程「man」java.util.EmptyStackException發生異常(未知源 在java.util.Stack.pop(Unknown Source)| at SimpleExpression.Evaluator.evaluate(SimpleLispExpression.java:306)(SimpleLispExpression.java:335) –

+0

@JohannMakramSalibBestowrous 在SimpleLispExpressionEvaluator.evaluateExprt(SimpleLispExpressionEvaluator.java:317)在SimpleLispExpressionEvaluator.main - 你'add'運營商被定義爲接受恰好2參數,但在(+(/ 2))'只有一個參數 –

+0

你能給我一個提示,我如何修復我的操作符來接受括號內的參數的數量?謝謝你所有的暗示到目前爲止:) –