我从教科书中得到了大部分代码,而且每件事似乎都有效。例如,如果我有后缀5 2 +它会给我7,这是正确的,但如果我有5 2 4 * / 7 - 那么它会抛出非法输入异常。当我摆脱非法输入异常时,它有效,但没有给出正确的答案。
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 :(得分:0)
您的算法存在缺陷。它所做的只是构建运算符和操作数的堆栈,然后向后计算表达式。那永远不会起作用。
我不明白你为什么要检查括号。后缀表达式中没有括号,因为从中缀到后缀的转换已经删除了括号。
此外,不需要一堆运营商。 postfix的整个想法是你可以在遇到它时评估每个操作符,并将结果推回到堆栈中。
基本算法是:
DispatchQueue.global(qos: .background).async {
// Write your code
}
因此,在评估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 -