表达树构造
表达树是一个二叉树的结构,用于衡量特定的表达。所有表达树的叶子都有一个数字字符串值。而所有表达树的非叶子都有另一个操作字符串值。
给定一个表达数组,请构造该表达的表达树,并返回该表达树的根。
您在真实的面试中是否遇到过这个题?
Yes
样例
对于 (2*6-(23+7)/(1+2))
的表达(可表示为 ["2" "*" "6" "-" "(" "23" "+" "7" ")" "/" "(" "1" "+" "2" ")"]). 其表达树如下:
[ - ]
/ \
[ * ] [ / ]
/ \ / \
[ 2 ] [ 6 ] [ + ] [ + ]
/ \ / \
[ 23 ][ 7 ] [ 1 ] [ 2 ] .
在构造该表达树后,你只需返回根节点[-]
。
自己的代码如下:java:
package campus.lintCode;
import sort.algorithm.Bubbling;
public class ExpressionTreeBuild {
public static void main(String[] args) {
// String[] expression=new String[]{"2", "*" ,"6" ,"-" ,"(", "23", "+", "7", ")", "/", "(", "1" ,"+" ,"2", ")"};
// System.out.println(build(expression));
String[] expression=new String[]{"2","*","6","-","(","23","+","7",")","/","(","1","+","2",")"};
System.out.println(build(expression));
}
/**
* @param expression: A string array
* @return: The root of expression tree
*/
public static ExpressionTreeNode build(String[] expression) {
// write your code here
int[] prio=new int[expression.length];
int valiLen= dealPrio( expression,prio);//处理后有效数据的长度
ExpressionTreeNode treeNode=buildFle( expression, prio,0,valiLen-1);
return treeNode;
}
/**
* @param expression
* @param prio
* 符号优先级处理
*/
public static int dealPrio(String[] expression,int[] prio)
{
int kuohao=0;//用于括号里面操作符号升级
for(int i=0;i<expression.length;i++)
{
switch(expression[i])
{
case "-":prio[i]=1+kuohao;break;
case "+":prio[i]=1+kuohao;break;
case "*":prio[i]=2+kuohao;break;
case "/":prio[i]=2+kuohao;break;
case "(": kuohao+=2;prio[i]=32767;break;
case ")":kuohao-=2;prio[i]=32767;break;
default:prio[i]=-32768;
}
}
int j=0;//对括号进行去除操作
for(int i=0;i<expression.length;i++)
{
if(expression[i]=="("||expression[i]==")")
{
continue;
}
else {
expression[j]=expression[i];
prio[j]=prio[i];
j++;
}
}
return j;//有小数据的长度
}
public static ExpressionTreeNode buildFle(String[] expression,int[] prio, int start,int end)
{
if(start==end)//此时只有有个值的点
{
ExpressionTreeNode treeNode=new ExpressionTreeNode(expression[start]);
return treeNode;
}
else {
//如果不只是有值
int prioOpe=Integer.MAX_VALUE;//记录优先级最低的操作符值
int currentnum=start;//记录最低的优先级操作符位置
//查找最小级别的操作符
for(int i=start;i<=end;i++)
{
if(prio[i]!=-32768&&prio[i]<prioOpe)
{
prioOpe=prio[i];
currentnum=i;
}
}
//当找到最小的操作符后,以此操作符为根做扩展
ExpressionTreeNode expressionTreeNode=new ExpressionTreeNode(expression[currentnum]);
expressionTreeNode.left=buildFle(expression, prio, start, currentnum-1);
expressionTreeNode.right=buildFle(expression, prio, currentnum+1, end);
return expressionTreeNode;
}
}
}
class ExpressionTreeNode {
public String symbol;
public ExpressionTreeNode left, right;
public ExpressionTreeNode(String symbol) {
this.symbol = symbol;
this.left = this.right = null;
}
}
写过一遍思路比较简单:
1.遍历记录表达字符的优先级:
+- 是一级,最低级,*/是二级,同时如果遇到括号,则括号里面的符号级别升高
2.将原始表达式中的括号删除掉,同时保证操作符优先级中的顺序
3.构造表达树,这里我使用的递归,结果正确,只是尼玛在lintcode上提示问题,看样子平台还是不一样,之前测试连HashMap都不能用……