问题
private class InputListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
String input = inputTextField.getText();
StringTokenizer strToken = new StringTokenizer(input, " ", false);
while (strToken.hasMoreTokens())
{
String i = strToken.nextToken();
int operand;
char operator;
try
{
operand = Integer.parseInt(i);
operandStack.push(operand);
}
catch (NumberFormatException nfe)
{
operator = i.charAt(0);
operatorStack.push(operator);
}
}
int result = sum (operandStack, operatorStack);
resultTextField.setText(Integer.toString(result));
}
My prefix expression code will only evaluate one expression at a time (i.e. + 3 1). I want it to evaluate multiple expressions in one user-input expression (i.e. * + 16 4 + 3 1). How can I edit the code provided to make it evaluate multiple expressions? Thank you for your help.
回答1:
To simply make your program do a bit more you can use a loop to keep operating on the operandStack
and pushing the result of the previous result to the stack. I left my println
statements in so you can see what its doing. Also I modified your method so it can sit inside a standalone main
method.
You should look into the Shunting-yard algorithm, its quite fun to implement and it is somewhat like what your doing here. http://en.wikipedia.org/wiki/Shunting-yard_algorithm
public static void main(String[] args) {
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
String input = "12 + 13 - 4";
StringTokenizer strToken = new StringTokenizer(input, " ", false);
while (strToken.hasMoreTokens()) {
String i = strToken.nextToken();
int operand;
char operator;
try {
operand = Integer.parseInt(i);
operandStack.push(operand);
} catch (NumberFormatException nfe) {
operator = i.charAt(0);
operatorStack.push(operator);
}
}
// loop until there is only 1 item left in the operandStack, this 1 item left is the result
while(operandStack.size() > 1) {
// some debugging println
System.out.println("Operate\n\tbefore");
System.out.println("\t"+operandStack);
System.out.println("\t"+operatorStack);
// perform the operations on the stack and push the result back onto the operandStack
operandStack.push(operate(operandStack, operatorStack));
System.out.println("\tafter");
System.out.println("\t"+operandStack);
System.out.println("\t"+operatorStack);
}
System.out.println("Result is: " + operandStack.peek());
}
/**
* Performs math operations and returns the result. Pops 2 items off the operandStack and 1 off the operator stack.
* @param operandStack
* @param operatorStack
* @return
*/
private static int operate(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop();
Integer a = operandStack.pop();
Integer b = operandStack.pop();
switch(op) {
case '-':
return b - a;
case '+':
return a + b;
default:
throw new IllegalStateException("Unknown operator '"+op+"'");
}
}
I left the operate
method (previously called sum
) as close to what you had it as possible, however I think that your code could be improved by simply passing 2 integers and a operator to the function. Making the function alter your stacks isnt a great thing and could lead to confusing problems.
Consider making your method signature this instead:
private static int operate(Integer a, Integer b, char operator) {
switch(operator) {
case '-':
return b - a;
case '+':
return a + b;
default:
throw new IllegalStateException("Unknown operator '"+operator+"'");
}
}
and then popping from the stack and passing those to the method. Keeping your stack altering code all in one place.
operandStack.push(operate(operandStack.pop(), operandStack.pop(), operatorStack.pop()));
来源:https://stackoverflow.com/questions/29594598/prefix-expression-to-evaluate-multiple-expressions-simultaneously