Postfix堆栈计算器

时间:2012-06-25 13:26:47

标签: java stack calculator postfix-notation

我为我的Java类创建了一个堆栈计算器来解决方程式,例如

2 + ( 2 * ( 10 – 4 ) / ( ( 4 * 2 / ( 3 + 4) ) + 2 ) – 9 )
2 + { 2 * ( 10 – 4 ) / [ { 4 * 2 / ( 3 + 4) } + 2 ] – 9 }

我们假设在代码中实现{ } [ ]。我只用括号做了。仅使用( )即可100%运行。当我尝试添加{ } [ ]时,它会变成香蕉。

这是我到目前为止所做的:

package stackscalc;

import java.util.Scanner;
import java.util.Stack;
import java.util.EmptyStackException;


class Arithmetic {
    int length;
    Stack stk;
    String exp, postfix;

    Arithmetic(String s) {
        stk = new Stack();
        exp = s;
        postfix = "";
        length = exp.length();

    }
    boolean isBalance() {
        boolean fail = false;
        int index = 0;

        try {
            while (index < length) {
                char ch = exp.charAt(index);

                switch(ch) {
                case ')':
                    stk.pop();
                    break;

                case '(':
                    stk.push(new Character(ch));
                    break;

                default:
                    break;
                }
                index++;
            }
        } catch (EmptyStackException e) {
            fail = true;
        }
        return stk.empty() && !fail;
    }
    void postfixExpression() {
        String token = "";
        Scanner scan = new Scanner(exp);
        stk.clear();

        while(scan.hasNext()) {
            token = scan.next();
            char current = token.charAt(0);

            if (isNumber(token)) {
                postfix = postfix + token + " ";
            } else if(isParentheses(current)) {
                if (current == '(') {
                    stk.push(current);
                } else {
                    Character ch = (Character) stk.peek();
                    char nextToken = ch.charValue();

                    while(nextToken != '(') {
                        postfix = postfix + stk.pop() + " ";

                        ch = (Character) stk.peek();

                        nextToken = ch.charValue();
                    }
                    stk.pop();
                }
            } else {
                if (stk.empty()) {
                    stk.push(current);
                } else {
                    Character ch = (Character) stk.peek();
                    char top = ch.charValue();

                    if (hasHigherPrecedence(top, current)) {
                        stk.push(current);
                    } else {
                        ch = (Character) stk.pop();

                        top = ch.charValue();

                        stk.push(current);

                        stk.push(top);
                    }
                }
            }
        }
        try {
            Character ch = (Character) stk.peek();
            char nextToken = ch.charValue();

            while (isOperator(nextToken)) {
                postfix = postfix + stk.pop() + " ";
                ch = (Character) stk.peek();
                nextToken = ch.charValue();
            }
        } catch (EmptyStackException e) {}
    }
    boolean isNumber(String s) {
        try {
            int Num = Integer.parseInt(s);
        } catch(NumberFormatException e) {
            return false;
        }
        return true;
    }
    void evaluateRPN() {
        Scanner scan = new Scanner(postfix);
        String token = "";
        stk.clear();

        while(scan.hasNext()) {
            try {
                token = scan.next();
                if (isNumber(token)) {
                    stk.push(token);
                } else {
                    char current = token.charAt(0);
                    double t1 = Double.parseDouble(stk.pop().toString());
                    double t2 = Double.parseDouble(stk.pop().toString());
                    double t3 = 0;

                    switch (current) {
                    case '+': {
                        t3 = t2 + t1;
                        stk.push(t3);
                        break;
                    }
                    case '-': {
                        t3 = t2 - t1;
                        stk.push(t3);
                        break;
                    }
                    case '*': {
                        t3 = t2 * t1;
                        stk.push(t3);
                        break;
                    }
                    case '/': {
                        t3 = t2 / t1;
                        stk.push(t3);
                        break;
                    }
                    default: {
                        System.out.println("Reverse Polish Notation was unable to be preformed.");
                    }
                }
            }

        } catch (EmptyStackException e) {}
    }
}
String getResult() {
    return stk.toString();
}

int stackSize() {
    return stk.size();
}

boolean isParentheses(char current) {
    if ((current == '(') || (current == ')')) {
        return true;
    } else {
        return false;
    }
}

boolean isOperator(char ch) {
    if ((ch == '-')) {
        return true;
    } else if ((ch == '+')) {
        return true;
    }
    else if ((ch == '*')) {
        return true;
    }
    else if((ch == '/')) {
        return true;
    } else {

    }
    return false;
}

boolean hasHigherPrecedence(char top, char current) {
    boolean HigherPre = false;

    switch (current) {
    case '*':
        HigherPre = true;
    break;

    case '/':
        HigherPre = true;
    break;

    case '+':

        if ((top == '*') || (top == '/') || (top == '-')) {
             HigherPre = false;
        } else {
             HigherPre = true;
        }

        break;

    case '-':
        if ((top == '*') || (top == '/') || (top == '-')) {
            HigherPre = false;
        } else {
            HigherPre = true;
        }
        break;

    default:
        System.out.println("Higher Precedence Unsuccessful was unable to be preformed.");
        break;
    }

    return HigherPre;


   }

    String getPostfix() {
        return postfix;
    }
}

2 个答案:

答案 0 :(得分:1)

我假设的是(),{}和[]在操作顺序方面都具有相同的权重,您只需要修改代码以便可以互换地允许所有三个。

如果是这种情况,我会使用matcher类进行简单的正则表达式检查,以查看您正在查看的当前字符是括号,大括号还是括号。

    //convert char to string
    String temp += currentChar;
    //this will check for (, [, and { (need escapes because of how regex works in java)
    Pattern bracePattern = Pattern.compile("[\(\{\[]");
    Matcher matcher = numPatt.matcher(temp);
    if(matcher.find()){
    //you know you have a grouping character
    }

此代码应该允许您查找所有打开的分组字符(只需在正则表达式中替换(,{和[for),}和]以查找结束字符)。这可以在你的isParenthesis()方法中使用。

答案 1 :(得分:0)

您可以使用类似的方法来简化检查'(','[[或'{')是否匹配。

static char getExpected(char val){
       char expected=' ';
        switch (val) {
            case '(':
                expected=')';
                break;
            case '[':
                expected=']';
                break;
            case '{':
                expected='}';
                break;
        }
       return expected;
   }