此程序应将中缀转换为后缀并使用ArrayStack评估后缀。
import java.util.Scanner;
public class Postfix {
//Infix expression string
public static String infix;
//Postfix expression string
public static String postfix;
//Top of operatorStack
public static char topOperator;
/**Converts an infix expression to postfix expression*/
public static String convertToPostfix(String infix) {
//Create operatorStack ArrayStack that contain character elements
StackInterface<Character> operatorStack = new ArrayStack(infix.length());
//Initialize a new empty postfix string
StringBuilder postfix = new StringBuilder();
//While the infix string still has character
for (int i = 0; i < infix.length(); i++) {
char nextCharacter = infix.charAt(i);
switch (nextCharacter) {
case '+' : case '-' : case '*' : case '/' :
// stack is not empty if infix expression is valid
while (!operatorStack.isEmpty() && (getPrecedence(nextCharacter) <= getPrecedence(operatorStack.peek()))) {
postfix.append(operatorStack.peek());
operatorStack.pop();
}
operatorStack.push(nextCharacter);
break;
case '(' : operatorStack.push(nextCharacter);
break;
case ')' : topOperator = operatorStack.pop();
while (topOperator != '(') {
postfix.append(topOperator);
topOperator = operatorStack.pop();
}
break;
default : postfix.append(nextCharacter);
break;
}
}
//While operatorStack is not empty
while (!operatorStack.isEmpty()) {
topOperator = operatorStack.pop();
postfix.append(topOperator);
}
return postfix.toString();
}
/**Determine the precedence of operator*/
private static int getPrecedence(char operator) {
if (operator == '(' || operator == ')' )
return 3;
else if (operator == '/' || operator == '*')
return 2;
else if (operator == '+' || operator == '-')
return 1;
else
return 0;
}
/**Evaluates a postfix expression*/
public static int evaluatePostfix(String postfix) {
//Create an empty Integer valueStack that contain the integer element
StackInterface<Integer> valueStack = new ArrayStack(postfix.length());
int operandTwo;
int operandOne;
//While the postfix string still has character
for (int i = 0; i < postfix.length(); i++) {
char nextCharacter = postfix.charAt(i);
if ( Character.isDigit(nextCharacter))
valueStack.push(nextCharacter - 48);
else if (nextCharacter == '+' || nextCharacter == '-' || nextCharacter == '*' || nextCharacter == '/') {
operandTwo = Integer.parseInt(valueStack.pop().toString());
operandOne = Integer.parseInt(valueStack.pop().toString());
switch (nextCharacter) {
case '+' : valueStack.push(operandOne + operandTwo);
break;
case '-' : valueStack.push(operandOne - operandTwo);
break;
case '*' : valueStack.push(operandOne * operandTwo);
break;
case '/' : valueStack.push(operandOne / operandTwo);
break;
} // End switch
} // End else loop
} //End for loop
return valueStack.peek();
}
/**Main method*/
public static void main(String args[]){
//Create a Scanner object
Scanner input = new Scanner(System.in);
System.out.println("Infix to Postfix Converter");
System.out.println("--------------------------");
//Prompt user to input the infix expression
System.out.print("\nPlease type an infix expression "
+ "\n[Digit used are between 1 to 9] : ");
String infixExp = input.nextLine();
//Convert infix expression into postfix
String postfixExp = convertToPostfix(infixExp);
//Print the infix expression
System.out.println("\n\tInfix expression : " + infixExp);
//Print the postfix expression
System.out.println("\tPostfix expression : " + postfixExp);
//Calculate and print evaluated value
System.out.println("\t\tValue\t = " + evaluatePostfix(postfixExp));
}
}
如果中缀表达式没有括号,我可以得到正确的后缀。
但是,如果我填写完整的括号,例如(1+1)
,我会收到此错误
线程中的异常&#34; main&#34; java.lang.IllegalStateException:Stack为空。 在A.ArrayStack.pop(ArrayStack.java:24) 在A.Postfix.convertToPostfix(Postfix.java:42) 在A.Postfix.main(Postfix.java:120)
如果我只是左括号&#39;(&#39;,它将打印在后缀中。与1+1*(6
一样,后缀输出为116(*+:
Infix to Postfix Converter
--------------------------
Please type an infix expression
[Digit used are between 1 to 9] : 1+1*(6
Infix expression : 1+1*(6
Postfix expression : 116(*+
Value = 7
这是通用的StackInterface类:
public interface StackInterface<T> {
//Adds a new object to the top of stack.
public void push(T object);
//Removes and returns the stack top entry.
/*If the stack is empty before the operation, null */
public T pop();
//Retrieves the stack top entry.
/*If the stack is empty before the operation, null */
public T peek();
//Return true if the stack is empty.
public boolean isEmpty();
//Removes all entries from the stack.
public void clear();
}
这是ArrayStack类:
public class ArrayStack implements StackInterface {
//Array of stack entries
private Object[] stack;
//Size of stack
private int size;
//Create stack with initial capacity
public ArrayStack(int initialCapacity) {
stack = new Object[initialCapacity];
}
//Adds an object to the top of stack.
public void push(Object object) {
if (size == stack.length)
resize();
stack[size++] = object;
}
//Removes and returns the top of stack.
public Object pop() {
if (size == 0) throw new IllegalStateException("Stack is empty.");
Object object = stack[--size];
stack[size] = null;
return object;
}
//Return the top of stack.
public Object peek() {
if (size == 0) throw new IllegalStateException("Stack is empty.");
return stack[size-1];
}
//Check if stack is empty
public boolean isEmpty() {
return (size == 0);
}
//Resize array stack
private void resize() {
Object[] tempStack = stack;
stack = new Object[2 * tempStack.length];
System.arraycopy(tempStack, 0, stack, 0, size);
}
//Clear the stack
public void clear() {
while(!isEmpty())
pop();
}
}
我认为第一个问题似乎在
public Object pop() {
if (size == 0) throw new IllegalStateException("Stack is empty.");
Object object = stack[--size];
stack[size] = null;
return object;
}
有人能找到解决方案吗?非常感谢任何帮助。
答案 0 :(得分:0)
问题在这里:
当你有像(1 + 1)
这样的字符串时当您遇到“+”时,弹出“(”并使用以下方式按“+”:
while (!operatorStack.isEmpty() && (getPrecedence(nextCharacter) <= getPrecedence(operatorStack.peek()))) {
postfix.append(operatorStack.peek());
operatorStack.pop();
}
所以在操作员堆栈中你只需要“+” 当你在操作员堆栈中遇到最后一个“)”时,你有“+”
case ')' : topOperator = operatorStack.pop(
while (topOperator != '(') {
postfix.append(topOperator);
topOperator = operatorStack.pop();
}
break;
你试图弹出“+”这是完美的但是在你的while循环中你再次尝试弹出,这是你得到堆栈空异常的地方。为什么不跟你说')'然后循环呢?