2014-10-20 5 views
0

Эта программа должна преобразовать инфикс в постфикс и оценить постфикс, используя ArrayStack.левая скобка печатается в ошибке postfix & right close error

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)); 
} 

}  

Я могу получить правильный постфикс, если выражение infix не имеет круглых скобок. Но, если я ставлю полную скобку, например, (1+1), я получаю эту ошибку

Исключение в нити «основной» java.lang.IllegalStateException: Стек пуст. в A.ArrayStack.pop (ArrayStack.java:24) в A.Postfix.convertToPostfix (Postfix.java:42) в A.Postfix.main (Postfix.java:120)

Если я просто положить левую скобку «(», он будет напечатан в постфиксе Как 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

Отладка показывает, что проблема в классе ArrayStack: public Object pop() {if (size == 0) throw new IllegalStateException ("Stack is empty."); –

+0

Что такое _ debug_? Я имею в виду шаг через ваш код с отладчиком или ручкой и бумагой и посмотреть, что происходит с вашими значениями. –

ответ

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 вы пытаетесь поп-музыку, где вы получаете исключение из пустого стека. Почему вы не смотрите на случай?), А затем зациклитесь?