左括号印在后缀&右括号错误

时间:2014-10-20 15:53:44

标签: java calculator postfix-notation infix-notation evaluate

此程序应将中缀转换为后缀并使用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;
}

有人能找到解决方案吗?非常感谢任何帮助。

1 个答案:

答案 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循环中你再次尝试弹出,这是你得到堆栈空异常的地方。为什么不跟你说')'然后循环呢?