Java使用分流场算法评估RPN

时间:2020-06-12 17:09:55

标签: java math methods

我有在网上找到的调车场算法:

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class ShuntingYardAlgorithm {

private enum Operator {
    ADD(1), SUBTRACT(2), MULTIPLY(3), DIVIDE(4);
    final int precedence;
    Operator(int p) {
        precedence = p;
    }
}

private Map<String, Operator> operatorMap = new HashMap<String, Operator>() {/**
     * 
     */
    private static final long serialVersionUID = 1L;

{
    put("+", Operator.ADD);
    put("-", Operator.SUBTRACT);
    put("*", Operator.MULTIPLY);
    put("/", Operator.DIVIDE);
}};

private boolean isHigherPrec(String op, String sub) {
    return (operatorMap.containsKey(sub) &&
            operatorMap.get(sub).precedence >= operatorMap.get(op).precedence);
}

public String shuntingYard(String infix) {
    StringBuilder output = new StringBuilder();
    Stack<String> stack = new Stack<String>();

    for (String token : infix.split("")) {
        //operator
        if (operatorMap.containsKey(token)) {
            while ( ! stack.isEmpty() && isHigherPrec(token, stack.peek())) {
                output.append(stack.pop()).append(' ');
            }
            stack.push(token);
        }
        //left parenthesis
        else if (token.equals("(")) {
            stack.push(token);
        }
        //right parenthesis
        else if (token.equals(")")) {
            while ( ! stack.peek().equals("(")) {
                output.append(stack.pop()).append(' ');
            }
            stack.pop();
        }
        //digit
        else {
            output.append(token).append(' ');
        }
    }

    while ( ! stack.isEmpty()) {
        output.append(stack.pop()).append(' ');
    }

    return output.toString();
}

}

评估者:

private static int evalRPN(String[] tokens) {
    int returnValue = 0;
    String operators = "+-*/";

    Stack<String> stack = new Stack<String>();

    for (String t : tokens) {
        if (!operators.contains(t)) {
            stack.push(t);
        } else {
            int a = Integer.valueOf(stack.pop());
            int b = Integer.valueOf(stack.pop());
            switch (t) {
            case "+":
                stack.push(String.valueOf(a + b));
                break;
            case "-":
                stack.push(String.valueOf(b - a));
                break;
            case "*":
                stack.push(String.valueOf(a * b));
                break;
            case "/":
                stack.push(String.valueOf(b / a));
                break;
            }
        }
    }

    returnValue = Integer.valueOf(stack.pop());

    return returnValue;
}

到目前为止,它们都工作良好,但是我对定界符用“”分隔的评估有问题,该定界符不允许使用两位数,例如23或更高。您能建议我做些什么来改进评估方法?

String output = new ShuntingYardAlgorithm().shuntingYard(algExp);
        algExp = output.replaceAll(" ", "");
        String[] outputArray = algExp.split("");
        return evalRPN(outputArray);

例如,我输入:256+3 结果:2 5 6 3 + 评估:6 + 3 = 9, ignores 2 and 5

1 个答案:

答案 0 :(得分:0)

遇到操作符或括号时,您的shuntingYard函数将丢弃output的内容。

在处理当前字符之前,您需要添加对output内容的检查。

    if (operatorMap.containsKey(token)) {
        // TODO: Check output here first, and create a token as necessary
        while ( ! stack.isEmpty() && isHigherPrec(token, stack.peek())) {
            output.append(stack.pop()).append(' ');
        }
        stack.push(token);
    }
    //left parenthesis
    else if (token.equals("(")) {
        // TODO: Check output here first, and create a token as necessary
        stack.push(token);
    }
    //right parenthesis
    else if (token.equals(")")) {
        // TODO: Check output here first, and create a token as necessary
        while ( ! stack.peek().equals("(")) {
            output.append(stack.pop()).append(' ');
        }
        stack.pop();
    }

此外,使用空字符串分割等效于一次仅将String迭代一个字符。使用infix迭代toCharArray()可能更具可读性

   for (char c : infix.toCharArray())