java 中缀的后缀,带有最少数量的括号

tzxcd3kk  于 2023-03-06  发布在  Java
关注(0)|答案(3)|浏览(118)

我正在寻找算法后缀中缀符号,这将产生最小数量的括号。
我发现,但它会产生很多很多括号:http://tajendrasengar.blogspot.com/2011/09/postfix-to-infix-algorithm.html

    • 例如**

输入:

<ONP>abcd*/+~

结果是:

<INF>~(a+b/(c*d))
ma8fv8wu

ma8fv8wu1#

如果你真的想要尽可能少的括号,你需要做的事情和你链接到的算法是类似的。

  • 应该为Stack中的每个 * 复合 * 操作数存储一个运算符。也就是说,操作数中使用的最后一个运算符。可以为此使用第二个Stack。如果操作数不是复合操作数,则可以将null与第二个Stack相加,因为没有运算符。
  • 不要用圆括号封装String,这在算法的其他地方完成(见下文)。

当您从每个Stack弹出前两个值时,您手头有3个运算符:

  • 当前操作员
  • 第一个操作数中最后使用的运算符(如果该运算符存在)
  • 第二个操作数中最后使用的运算符(如果该运算符存在)

根据这三个运算符,在组合第一个和/或第二个操作数之前,应该用括号将它们封装起来。
可以使用运算符优先级来确定是否应该使用括号。顺序如下:(none), {"*", "/"}, {"+", "-"}

  • 当且仅当第一个操作数的运算符优先级低于当前运算符时,才需要使用括号。
  • 如果第二个操作数的运算符的优先级低于当前运算符,或者它们的优先级相等,而当前运算符是"/""-",则第二个操作数需要括号。

剩下的应该按照你的算法描述的方式来做。

z9ju0rcb

z9ju0rcb2#

我找到了一个例子来解决这个问题,在python的ast库中有一个_Unparsing类来反解析AST树。
库中有一个require_parens函数用于检查圆括号。
示例:

~% python3.11
>>> import ast
>>> ast.unparse(ast.parse("(-(-1+2)+((2*3))-4)"))
'-(-1 + 2) + 2 * 3 - 4'
>>>

如果需要,可以使用ast.walk函数将AST树转换为后缀表示法。Link

dwbf0jvd

dwbf0jvd3#

实现方法如下:

public class PostfixToInfixConverter implements ExpressionConverter {

@Override
public String convert(String postfix) {
    String[] expressions = postfix.split("\\s");
     Deque<Expression> stack = new LinkedList<Expression>();
    for (String exp : expressions) {
        if (exp.equals("+") || exp.equals("-")) {
            String right = stack.pop().getExpression();
            String left = stack.pop().getExpression();
            Expression newExp = new Expression(right + exp + left, exp);
            stack.push(newExp);
        } else if (exp.equals("*") || exp.equals("/")) {
            String right = correctExpression(stack.pop());
            String left = correctExpression(stack.pop());
            stack.push(new Expression(right +  exp +  left, exp));
        } else {
            stack.push(new Expression(exp, ""));
        }
    }
    return stack.pop().getExpression();
}

private String correctExpression(Expression exp) {
    String result = exp.getExpression();
    if (exp.getOperatorUsed().equals("+") || exp.getOperatorUsed().equals("-")) {
        result = "(" + result + ")";
    }
    return result;
}

private static class Expression {
    String expression;
    String operatorUsed;
    public Expression(String exp, String operator) {
        this.expression = exp;
        this.operatorUsed = operator;
    }
    public String getExpression() {
        return expression;
    }
    public String getOperatorUsed() {
        return operatorUsed;
    }       
}

}
下面是单元测试

@Test
public void test() {
    ExpressionConverter converter = new PostfixToInfixConverter();
    assertThat(converter.convert("1 2 * 3 4 * + 5 *"), equalTo("5*(4*3+2*1)"));
    assertThat(converter.convert("a b + c + 2 *"), equalTo("2*(c+b+a)"));
}

相关问题