[英]Reduce number of parentheses for a binary expression tree
I have a function that receives a binary expression tree and returns a String with the expression in-order. 我有一个函数,该函数接收二进制表达式树,并按顺序返回带有表达式的String。 The only "problem" is that the resulting expression have too many parentheses,
唯一的“问题”是,结果表达式的括号过多,
eg: The function returns (a + (b * c)), but it can be reduced to a + b * c. 例如:函数返回(a +(b * c)),但可以将其简化为a + b * c。
It is defined with the binary operators +, -, *, /, and the unary operator _ (negative). 它由二进制运算符+,-,*,/和一元运算符_(负)定义。
What I really want to know is if I can modify the already existing function to reduce the number of parentheses in an efficient way, or create another function that operates with the String of the in-order expression. 我真正想知道的是,我是否可以修改现有的函数以有效地减少括号的数量,还是创建另一个对有序表达式的String进行操作的函数。
The function is as follows: 功能如下:
private static String infijo(ArbolB t){
String s = "";
if (t != null) {
String info = String.valueOf(t.info);
if ("+-*/".contains(info)) s += "(";
if ("_".contains(info)) s += "-(";
s += infijo(t.left) + (info.equals("_") ? "" : info) + infijo(t.right);
if ("+-*/_".contains(String.valueOf(t.info))) s += ")";
}
return s;
}
Where ArbolB is a binary tree defined by: 其中ArbolB是由以下项定义的二叉树:
public class ArbolB {
ArbolB right;
ArbolB left;
Object info;
public ArbolB(Object info, ArbolB right, ArbolB left){
this.info = info;
this.right = right;
this.left = left;
}
}
After writing this whole thing out, I realized that I didn't really answer your question properly (my solution ignores PEMDAS and just matches pairs, d'oh!). 将整个内容写完之后,我意识到我并没有真正正确地回答您的问题(我的解决方案忽略了PEMDAS,只是配对了,噢!)。 So, take from this what you can... I'm not throwing it out :P
因此,从中获取您所能...我不会把它扔掉:P
I think you COULD solve this either way, but here would be my preferred method, using and trusting what you already have. 我认为您可以通过任何一种方式解决此问题,但这将是我的首选方法,使用并信任您已经拥有的内容。 There's probably a good way to use nodes to do this, but why not use what you have, right?
使用节点执行此操作可能是一种好方法,但是为什么不使用现有资源呢?
Starting from the point where you have your expression as a string (eg "((2*2) + _(3+3))" you could try something like: 从将表达式表示为字符串的点开始(例如“(((2 * 2)+ __(3 + 3)))”),可以尝试以下操作:
public string RemoveUnnecessaryParens(string expression)
{
readonly string openParen = "(";
readonly string closeParen = ")";
// char array would also work for this
// multiple ways to track "balance" of parens, lets use int
int unclosedParenCount = 0;
string toReturn = "";
// iterate through the expression
for (int i = 0; i < expression.Length; i++)
{
string current = expression.Substring(i,1);
if (openParen == current)
unclosedParenCount++;
else if (closedParen == current)
unclosedParenCount--;
else
toReturn += current;
if (unclosedParenCount < 0) throw new UnbalancedExpressionException(); // One more close than open! Uh oh!
}
if (0 != unclosedParenCount) throw new UnbalancedExpressionException(); // One more open than close at the end! Uh oh!
else return toReturn;
}
Make sense? 说得通?
Well, after thinking it a while, I got to a solution myself, by adding a priority function for determining when parentheses were necessary, and a variable that indicates if the operation was on the left or the right side of the formula, this because a-b+c don't need parentheses, but c+(ab) do need them. 好了,考虑了一会儿之后,我自己解决了一个问题,添加了一个优先级函数来确定何时需要使用括号,并添加了一个变量,该变量指示操作是在公式的左侧还是右侧,这是因为-b + c不需要括号,但是c +(ab)确实需要括号。
private static String infijo(ArbolB t, int priority, boolean right) {
String s = "";
int oP = 0;
if (t != null) {
String info = String.valueOf(t.info);
int pi = priority(info);
if ("+-*/".contains(info)) {
/* this only adds parentheses if the operation has higher priority or if the
operation on the right side should be done before the one on the left side*/
if ("+-*/".contains(info)) {
if (pi/2 < priority/2) s += "(";
else s += pi/2 == priority/2 && pi != priority && right ? "(" : "";
oP = priority; //stores the old priority
priority= pi; //priority of the new operator
}
}
if ("_".contains(info)) {
s += "-";
oP = priority;
priority = pi;
}
s += infijo(t.left, priority, false) + (info.equals("_") ? "" : info)
+ infijo(t.right, priority, true);
if ("+-*/".contains(info)) {
// adds the closing parentheses following the same rules as for the opening ones
if (priority / 2 < oP / 2) s += ")";
else s += priority / 2 == oP / 2 && priority != oP && right ? ")" : "";
}
}
return s;
}
private static int priority(String op) {
if ("_".contains(op)) return 4;
if ("/".contains(op)) return 3;
if ("*".contains(op)) return 2;
if ("-".contains(op)) return 1;
return 0;
}
@Override
public String toString() {
ArbolB f = getFormula(); //this returns the Binary Expression Tree
return infijo(f, Integer.MIN_VALUE, false);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.