问题
I am looking for algorithm postfix to infix notation which will produce the minimum number of the parentheses.
I have found that but it will produce many, many parentheses: http://tajendrasengar.blogspot.com/2011/09/postfix-to-infix-algorithm.html
For example
The input:
<ONP>abcd*/+~
The result:
<INF>~(a+b/(c*d))
回答1:
What you need to do if you really want as few parentheses as possible, is similar to what the algorithm you linked to says. However...
- You should store an operator for each composite operand in the
Stack
. Namely, the last operator used in the operand. You could use a secondStack
for this. If the operand is not composite, you could addnull
to the secondStack
, since there is no operator. - Don't encapsulate the resulted
String
with parentheses. That is done elsewhere in the algorithm (see below).
When you pop the top two values from each of the Stack
s, you have 3 operators at hand:
- The current operator
- The last used operator in the first operand (if the operator exists)
- The last used operator in the second operand (if the operator exists)
Depending on these three operators, you should encapsulate the first and/or second operand with parentheses, before combining them.
You could use operator precedence to determine whether there should be parentheses. The order goes like this: (none), {"*", "/"}, {"+", "-"}
- The first operand needs parentheses if and only if its operator has a lower precedence than the current operator.
- The second operand needs parentheses if its operator has a lower precedence than the current operator, or if they have equal precedence where the current operator is either
"/"
or"-"
.
The rest should be done the way your algorithm described.
回答2:
Here is the implementation:
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;
}
}
}
Here is the unit tests
@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)"));
}
来源:https://stackoverflow.com/questions/15780817/postfix-to-infix-with-minimum-number-of-parentheses