Java 回答错误

Java 回答错误,java,calculator,rpn,Java,Calculator,Rpn,我需要做一个计算器,它接受中缀表达式并使用rpn来计算它 Java代码: public RpnCalculator() { } public float eval(float arg1, float arg2, String operator) { switch (operator) { case PLUS: return arg1 + arg2; case MINUS: return arg2 - a

我需要做一个计算器,它接受中缀表达式并使用rpn来计算它

Java代码:

public RpnCalculator() {

}


public float eval(float arg1, float arg2, String operator) {
    switch (operator) {
        case PLUS:
            return arg1 + arg2;
        case MINUS:
            return arg2 - arg1;
        case MULTIPLICATION:
            return arg1 * arg2;
        case DIVISION:
            return arg2 / arg1;
        default:
            return 0;
    }
}

public String evaluateInfixExpression(String expression) {
    Stack<String> operators = new Stack<>();
    String[] args = expression.split(SPACE);
    Stack<String> values = new Stack<>();

    for (String arg : args) {
        if (isANumber(arg)) {
            values.push(arg);
            continue;
        }
        if (operators.isEmpty()) {
            operators.push(arg);
        } else if (precedence(arg) <= precedence(operators.peek())) {
            float result = eval(Float.parseFloat(values.pop()), Float.parseFloat(values.pop()), operators.pop());
            values.push(String.valueOf(result));
            operators.push(arg);
        } else if (precedence(arg) > precedence(operators.peek())) {
            operators.push(arg);
        }
    }


    while (!operators.isEmpty()) {
        float result = eval(Float.parseFloat(values.pop()), Float.parseFloat(values.pop()), operators.pop());
        values.push(String.valueOf(result));
    }

    return expression;
}

public int precedence(String operator){
    if (operator.equals(PLUS) || operator.equals(MINUS)){
        return 1;
    }
    return 2;

}

public boolean isANumber(String number) {
    if (number.matches("-?\\d+")) {
        return true;
    }
    return false;
}
public RpnCalculator(){
}
公共浮点值(浮点arg1、浮点arg2、字符串运算符){
开关(操作员){
案例补充:
返回arg1+arg2;
减号:
返回arg2-arg1;
大小写乘法:
返回arg1*arg2;
案件司:
返回arg2/arg1;
违约:
返回0;
}
}
公共字符串求值infixexpression(字符串表达式){
堆栈运算符=新堆栈();
字符串[]args=expression.split(空格);
堆栈值=新堆栈();
for(字符串arg:args){
if(ISA编号(arg)){
值。推送(arg);
继续;
}
if(operators.isEmpty()){
运算符。推送(arg);
}else if(优先级(arg)优先级(operators.peek()){
运算符。推送(arg);
}
}
而(!operators.isEmpty()){
float result=eval(float.parseFloat(values.pop()),float.parseFloat(values.pop()),operators.pop());
value.push(String.valueOf(result));
}
返回表达式;
}
公共整数优先级(字符串运算符){
if(运算符等于(正)| |运算符等于(负)){
返回1;
}
返回2;
}
公共布尔值(字符串编号){
if(匹配的数字(“-?\\d+”){
返回true;
}
返回false;
}
}

它运行良好,只是有时会给出错误的答案。。。 对我来说,我似乎遵循了调车场算法的原则,但正如你所看到的,我实际上并没有将中缀转换为后缀,但我尝试在运行中评估参数,这可能是一个问题

例如,表达式-2+6*8/3*18-33/3-11的计算结果为286,而不是264。应该有一些我没注意到的错误,已经两天了,请帮助我。此外,我在堆栈上阅读了大量关于RPN的文章,但似乎每个人都有不同的问题,所以我没有找到我的案例的答案


多谢各位

我不是RPN专家,但我注意到您正在按从右到左的顺序评估参数,因此,在评估乘法和除法之后,您将得到以下结果:

operators = + - -
values = -2 288 11 11
然后执行(从右到左的顺序):

这并没有给你正确的结果

如果按从左到右的顺序进行计算,则得到:

-2 + 288 = 286
286 - 11 = 275
276 - 11 = 264
所以我稍微修改了你的代码:

public String evaluateInfixExpression(String expression) {
    Deque<String> operators = new LinkedList<>();
    String[] args = expression.split(SPACE);
    Deque<String> values = new LinkedList<>();

    for (String arg : args) {
        if (isANumber(arg)) {
            values.push(arg);
            continue;
        }
        if (operators.isEmpty()) {
            operators.push(arg);
        } else if (precedence(arg) <= precedence(operators.peek())) {
            float result = eval(Float.parseFloat(values.pop()), Float.parseFloat(values.pop()), operators.pop());
            values.push(String.valueOf(result));
            operators.push(arg);
        } else if (precedence(arg) > precedence(operators.peek())) {
            operators.push(arg);
        }
    }

    while (!operators.isEmpty()) {
        String v1 = values.removeLast();
        String v2 = values.removeLast();
        float result = eval(Float.parseFloat(v2), Float.parseFloat(v1), operators.removeLast());
        values.addLast(String.valueOf(result));
    }
    return expression;
}
public String evaluateInfixExpression(字符串表达式){
Deque运算符=新的LinkedList();
字符串[]args=expression.split(空格);
Deque values=新链接列表();
for(字符串arg:args){
if(ISA编号(arg)){
值。推送(arg);
继续;
}
if(operators.isEmpty()){
运算符。推送(arg);
}else if(优先级(arg)优先级(operators.peek()){
运算符。推送(arg);
}
}
而(!operators.isEmpty()){
字符串v1=值。removeLast();
字符串v2=values.removeLast();
float result=eval(float.parseFloat(v2)、float.parseFloat(v1)、operators.removeLast());
values.addLast(String.valueOf(result));
}
返回表达式;
}

我不是RPN专家,但我注意到您正在按从右到左的顺序评估参数,因此,在评估乘法和除法之后,您将得到以下结果:

operators = + - -
values = -2 288 11 11
然后执行(从右到左的顺序):

这并没有给你正确的结果

如果按从左到右的顺序进行计算,则得到:

-2 + 288 = 286
286 - 11 = 275
276 - 11 = 264
所以我稍微修改了你的代码:

public String evaluateInfixExpression(String expression) {
    Deque<String> operators = new LinkedList<>();
    String[] args = expression.split(SPACE);
    Deque<String> values = new LinkedList<>();

    for (String arg : args) {
        if (isANumber(arg)) {
            values.push(arg);
            continue;
        }
        if (operators.isEmpty()) {
            operators.push(arg);
        } else if (precedence(arg) <= precedence(operators.peek())) {
            float result = eval(Float.parseFloat(values.pop()), Float.parseFloat(values.pop()), operators.pop());
            values.push(String.valueOf(result));
            operators.push(arg);
        } else if (precedence(arg) > precedence(operators.peek())) {
            operators.push(arg);
        }
    }

    while (!operators.isEmpty()) {
        String v1 = values.removeLast();
        String v2 = values.removeLast();
        float result = eval(Float.parseFloat(v2), Float.parseFloat(v1), operators.removeLast());
        values.addLast(String.valueOf(result));
    }
    return expression;
}
public String evaluateInfixExpression(字符串表达式){
Deque运算符=新的LinkedList();
字符串[]args=expression.split(空格);
Deque values=新链接列表();
for(字符串arg:args){
if(ISA编号(arg)){
值。推送(arg);
继续;
}
if(operators.isEmpty()){
运算符。推送(arg);
}else if(优先级(arg)优先级(operators.peek()){
运算符。推送(arg);
}
}
而(!operators.isEmpty()){
字符串v1=值。removeLast();
字符串v2=values.removeLast();
float result=eval(float.parseFloat(v2)、float.parseFloat(v1)、operators.removeLast());
values.addLast(String.valueOf(result));
}
返回表达式;
}

对于RPN,首先应将中缀形式转换为后缀形式。为此,您可以使用Dijkstra提供的

此算法的示例实现:

public class ShuntingYard {
    private static boolean isHigerPrec(String op, String sub) {
        return (ops.containsKey(sub) && ops.get(sub).precedence >= ops.get(op).precedence);
    }

    public static Stack<String> postfix(String infix) {
        Stack<String> output = new Stack<>();
        Deque<String> stack  = new LinkedList<>();

        for (String token : infix.split("\\s")) {
            if (ops.containsKey(token)) {
                while ( ! stack.isEmpty() && isHigerPrec(token, stack.peek()))
                    output.push(stack.pop());
                    stack.push(token);
                }  else {
                    output.push(token);
                }
        }

        while ( ! stack.isEmpty()) 
            output.push(stack.pop());
        return reverse(output);
    }

    private static Stack<String> reverse(Stack<String> original) {
        Stack<String> reverse = new Stack<>();
        while(!original.isEmpty()) reverse.push(original.pop());
        return reverse;
   }
}
公共级调车场{
私有静态布尔值isHigerPrec(字符串op,字符串sub){
返回(ops.containsKey(sub)和&ops.get(sub.priority>=ops.get(op.priority));
}
公共静态堆栈后缀(字符串中缀){
堆栈输出=新堆栈();
Deque stack=newlinkedlist();
用于(字符串标记:中缀.split(\\s)){
if(操作容器(令牌)){
而(!stack.isEmpty()&&isHigerPrec(token,stack.peek())
output.push(stack.pop());
堆栈推送(令牌);
}否则{
输出推送(令牌);
}
}
而(!stack.isEmpty())
output.push(stack.pop());
返回反向(输出);
}
私有静态堆栈反转(堆栈原始){
堆栈反向=新堆栈();
而(!original.isEmpty())reverse.push(original.pop());
反向返回;
}
}
操作类:

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

    public static Map<String, Operator> ops = new HashMap<String, Operator>() {{
        put("+", Operator.ADD);
        put("-", Operator.SUBTRACT);
        put("*", Operator.MULTIPLY);
        put("/", Operator.DIVIDE);
    }};

    public static Operator fromString(String str){
        return ops.get(str);
    }
}
公共枚举运算符{
加(1)、减(1)、乘(2)、除(2);
最终整数优先;
运算符(int p){优先级=p;}
公共静态映射ops=newhashmap(){{
put(“+”,运算符.ADD);
put(“-”,运算符。减法);
put(“*”,运算符。乘法);
put(“/”,Oper
public enum Operator {
    ADD(1), SUBTRACT(1), MULTIPLY(2), DIVIDE(2);
    final int precedence;
    Operator(int p) { precedence = p; }

    private static Map<String, Operator> ops = new HashMap<String, Operator>() {{
        put("+", Operator.ADD);
        put("-", Operator.SUBTRACT);
        put("*", Operator.MULTIPLY);
        put("/", Operator.DIVIDE);
    }};

    public static Operator fromString(String token){
        return ops.get(token);
    }

    public static boolean isOperator(String token) {
        return ops.containsKey(token);
    }

    public boolean hasHigherPrecedenceThan(String token) {
        return isOperator(token) && this.precedence >= fromString(token).precedence;
    }
}