2013-04-10 3 views
1

Принесите меня, я немного пожарен прямо сейчас, чтобы получить все это вместе, но я на последнем этапе. Я сделал калькулятор в java, который принимает уравнение инфикса, а затем изменяет его на постфикс. Он также принимает переменные! Я сделал так, чтобы мой постфикс включал отрицательные числа из infix. Это будет выглядеть так:Вычислить негативы в калькуляторе стека

infix: 1+-2*(4/2) 
postfix: 12_42/*+ 

Так, очевидно, я получил это работает, где негативы '_' в постфикса. Круто, да? Хорошо, но теперь мне нужно, чтобы мой калькулятор прочитал их, и я просто получаю мозговой пучок от того, где он находится в стеке, и что я делаю, чтобы заставить его работать, не создавая условия для всех форм операндов. Вот что у меня есть:

import java.util.Stack; 

/** 
* 
* @author rtibbetts268 
*/ 
public class InfixToPostfix 
{ 
     /** 
     * Operators in reverse order of precedence. 
     */ 
    private static final String operators = "-+/*_"; 
    private static final String operands = "x"; 

    /*public int evalInfix(String infix) 
    { 
     return evaluatePostfix(convert2Postfix(infix)); 
    }*/ 

    public String xToValue(String postfixExpr, String x) 
    { 
     char[] chars = postfixExpr.toCharArray(); 
     StringBuilder newPostfixExpr = new StringBuilder(); 

     for (char c : chars) 
     { 
      if (c == 'x') 
      { 
       newPostfixExpr.append(x); 
      } 
      else 
      { 
       newPostfixExpr.append(c); 
      } 
     } 
     return newPostfixExpr.toString(); 
    } 

    public String convert2Postfix(String infixExpr) 
    { 
     char[] chars = infixExpr.toCharArray(); 
     StringBuilder in = new StringBuilder(infixExpr.length()); 

     for (int i = 0; i<chars.length; i++) 
     { 
      if (infixExpr.charAt(i) == '-') 
      { 
       if (i == 0) 
       { 
       in.append('_'); 
       } 
       else if(isOperand(infixExpr.charAt(i + 1))) 
       { 
        if (i != infixExpr.length()) 
        { 
        if (isOperator(infixExpr.charAt(i-1))) 
         in.append('_'); 
        } 
        else 
        { 
         in.append(infixExpr.charAt(i)); 
        } 
       } 
       else 
       { 
        in.append(infixExpr.charAt(i)); 
       } 
      } 
      else 
      { 
       in.append(infixExpr.charAt(i)); 
      } 
     } 

     chars = in.toString().toCharArray(); 
     Stack<Character> stack = new Stack<Character>(); 
     StringBuilder out = new StringBuilder(in.toString().length()); 

     for (char c : chars) 
     { 
      if (isOperator(c)) 
      { 
       while (!stack.isEmpty() && stack.peek() != '(') 
       { 
        if (operatorGreaterOrEqual(stack.peek(), c)) 
        { 
         out.append(stack.pop()); 
        } 
        else 
        { 
         break; 
        } 
       } 
       stack.push(c); 
      } 
      else if (c == '(') 
      { 
       stack.push(c); 
      } 
      else if (c == ')') 
      { 
       while (!stack.isEmpty() && stack.peek() != '(') 
       { 
        out.append(stack.pop()); 
       } 
       if (!stack.isEmpty()) 
       { 
        stack.pop(); 
       } 
      } 
      else if (isOperand(c)) 
      { 
       out.append(c); 
      } 
     } 
     while (!stack.empty()) 
     { 
      out.append(stack.pop()); 
     } 
     return out.toString(); 
    } 

    public int evaluatePostfix(String postfixExpr)//YBEYFCNUNKJKDV IT'S RIGHT HERE!!! 
    { 
     char[] chars = postfixExpr.toCharArray(); 
     Stack<Integer> stack = new Stack<Integer>(); 
     for (char c : chars) 
     { 
      if (isOperand(c)) 
      { 
       stack.push(c - '0'); // convert char to int val 
      } 
      else if (isOperator(c)) 
      { 
       int op1 = stack.pop(); 
       int op2 = stack.pop(); 
       int result; 
       switch (c) { 
        case '_': 
         result = op1 * -1; 
         //stack.push(result); 
         //break; 
        case '*': 
         result = op1 * op2; 
         stack.push(result); 
         break; 
        case '/': 
         result = op2/op1; 
         stack.push(result); 
         break; 
        case '+': 
         result = op1 + op2; 
         stack.push(result); 
         break; 
        case '-': 
         result = op2 - op1; 
         stack.push(result); 
         break; 
       } 
      } 
     } 
     return stack.pop(); 
    } 

    private int getPrecedence(char operator) 
    { 
     int ret = 0; 
     if (operator == '-' || operator == '+') 
     { 
      ret = 1; 
     } 
     else if (operator == '*' || operator == '/') 
     { 
      ret = 2; 
     } 
     if (operator == '_') 
     { 
      ret = 3; 
     } 
     return ret; 
    } 

    private boolean operatorGreaterOrEqual(char op1, char op2) 
    { 
     return getPrecedence(op1) >= getPrecedence(op2); 
    } 

    private boolean isOperator(char val) 
    { 
     return operators.indexOf(val) >= 0; 
    } 

    private boolean isOperand(char val) 
    { 
     return operands.indexOf(val) >= 0; 
    } 

} 

Я бы опубликовал меньше, но все это имеет тенденцию работать сплоченно, поэтому я объясню. Посмотрите внимательно на метод, который называется evaluatePostfix() (он является третьим сверху).

Здесь класс может принимать постфиксное выражение, такое как указанное выше, и вычисляет его. Он вычисляет выражение со всеми положительными целыми числами, но когда я пытался реализовать его, чтобы изменить число до отрицательного, прежде чем он фактически выполнил какую-либо математику, он переходит в kaputt.

Может ли кто-нибудь помочь мне с фиксацией этого конкретного метода, чтобы он работал? Мне нужно это для вычисления отрицательных целых чисел, а также положительных.

+0

Расчетный калькулятор стека достаточно прост. Пока у вас есть значения во входном потоке, нажмите их. Когда вы сталкиваетесь с оператором во входном потоке, выполните его в верхнем элементе (-ях) стека, удалив эти элементы, затем нажмите результат. –

+0

Очевидно, вы относитесь к '_' как к оператору отрицания, поэтому он выталкивает верхний элемент, отрицает его и толкает результат. –

ответ

2

В основном проблема заключается в попытке выскочить из пустого стека для случая «_». То, что вам нужно сделать, - это попытаться вывести op2 из стека для случаев «*/+ -», а не «_».

public int evaluatePostfix(String postfixExpr) 
{ 
    char[] chars = postfixExpr.toCharArray(); 
    Stack<Integer> stack = new Stack<Integer>(); 
    for (char c : chars) 
    { 
     if (isOperand(c)) 
     { 
      stack.push(c - '0'); // convert char to int val 
     } 
     else if (isOperator(c)) 
     { 
      int op1 = stack.pop(); 
      int op2; 
      int result; 
      switch (c) { 
       case '_': 
        result = op1 * -1; 
        stack.push(result); 
        break; 
       case '*': 
        op2 = stack.pop(); 
        result = op1 * op2; 
        stack.push(result); 
        break; 
       case '/': 
        op2 = stack.pop(); 
        result = op2/op1; 
        stack.push(result); 
        break; 
       case '+': 
        op2 = stack.pop(); 
        result = op1 + op2; 
        stack.push(result); 
        break; 
       case '-': 
        op2 = stack.pop(); 
        result = op2 - op1; 
        stack.push(result); 
        break; 
      } 
     } 
    } 
    return stack.pop(); 
} 
Смежные вопросы