2017-10-13 6 views
0

ほとんどのコードがテキストブックから抜け出し、すべてのものが動作しているようです。例えば、私がpostfix 5 2 +を持っていれば、それは私に7を与えますが、それは正しいですが、5 2 4 */7があれば、それは不正な入力例外をスローします。私が違法入力例外を取り除くと、正しく動作しますが、正しい答えが得られません。2つ以上の数字が入力された場合、後置式の評価中に不正な入力例外が発生する

import java.util.*; 
import java.util.regex.Pattern; 

//Here is my class and main method 


public class postFix { 

    public static final Pattern UNSIGNED_DOUBLE = Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?"); 
    public static final Pattern CHARACTER = Pattern.compile("\\S.*?"); 


     public static Double postfixEvaluate (String expression) { 

      Stack<Double> numbers = new Stack<Double>(); //Stack for numbers 
      Stack<Character> operators = new Stack<Character>(); //Stack for ops 

      Scanner input = new Scanner(expression); 
      String next; 

      while (input.hasNext())   //Iterator is used (hasNext) 
      { 
       if (input.hasNext(UNSIGNED_DOUBLE)) 
       { // if next input is a number 
        next = input.findInLine(UNSIGNED_DOUBLE); 
        numbers.push(new Double(next)); //adding nums to the number stack 
       } 

       else 
        { //The next input is an operator 

        next = input.findInLine(CHARACTER); 

        switch (next.charAt(0)) 
        { 
         case '+': 
         case '-': 
         case '*': 
         case '/': 
          operators.push(next.charAt(0)); //adding operators to operator stack 
          break; 
         case ')': 
          evaluateStackTops(numbers, operators); 
          break; 
         case '(': 
          break; 
        default: //Illegal Character 
         throw new IllegalArgumentException("Illegal Character"); 
        } 
       } 
      } 

//This what seems to be throwing the exception but I got this right out of the book 

     if (numbers.size() != 1) 

       throw new IllegalArgumentException("Illegal Input"); 

      return numbers.pop(); 
     } 

     public static void evaluateStackTops (Stack<Double> numbers, Stack<Character> operators) 
     { 
      double operand1 , operand2; 

      //check that the stacks have enough items, and get the two operands 
      if ((numbers.size()<2)||(operators.isEmpty())) { 
       throw new IllegalArgumentException("Illegal Expression");} 
       operand2 = numbers.pop(); 
       operand1 = numbers.pop(); 

      //carry out an operation based on the operator on top of the stack 

     for (int i = 0; i < numbers.size(); i++) { 
       switch (operators.pop()) { 
        case '+': 
         numbers.push(operand1 + operand2); 
         break; 
        case '-': 
         numbers.push(operand1 - operand2); 
         break; 
        case '*': 
         numbers.push(operand1 * operand2); 
         break; 
        case '/': 
         numbers.push(operand1/operand2); 
         break; 
        default: 
         throw new IllegalArgumentException("Illegal Operator"); 
       } 
      } 


    public static void main(String[] args) { 
     //String expression; 
     //Scanner input = new Scanner(expression); 

     System.out.println(postFix.postfixEvaluate("(2 3 5 */)")); 

    } 
} 
+0

あなたが変更した場合= 1 <= 1に、それが働くだろうか? – Assafs

+0

いいえ、スタック内のすべての数値と演算子を読み取っていないようです。私は何かを逃していない限り、なぜそれがないだろうか分からない –

+0

あなたは何の答えを期待していますか? '5 2 4 */7-'は中置式'(5 /(2 * 4) - 7')を表していますか? –

答えて

0

アルゴリズムに欠陥があります。それは、演算子とオペランドのスタックを構築し、その式を後方に評価するだけです。それは決してうまくいかない。

括弧をチェックする理由がわかりません。 inixからpostfixへの変換で既にカッコが削除されているので、後置式にはカッコがありません。

また、演算子のスタックは必要ありません。 postfixの考え方は、それぞれの演算子が遭遇したときに各演算子を評価し、その結果をスタックに戻すことができるということです。

基本的なアルゴリズムは以下のとおりです。

while not end of input 
    read next token 
    if token is a number 
     push on numbers stack 
    else if token is operator 
     pop value2 and value1 from stack 
     result = evaluate value1 <operator> value2 
     push result to numbers stack 
    else 
     invalid input 
end while 
// at this point, there should be 1 value on numbers stack 

5 2 4 */7 -を評価するときに、シーケンスは次のとおりです!

push 5 
push 2 
push 4 
// operator * read here 
pop 4 
pop 2 
evaluate 2 * 4 
push 8 
// operator/read here 
pop 8 
pop 5 
evaluate 5/8 
push 0.625 
push 7 
// operator - read here 
pop 7 
pop 0.625 
evaluate 0.625 - 7 
push -6.375 
// end of input here 
pop final result 
+0

ありがとう!多くの意味があります。 –

関連する問題