表达式求值的另外一种实现方式--表达式树

计算器求值的常规解法是使用栈分别保存操作数和操作符,具体代码如下

// 这里是开头






// 这里是结尾
栈求解表达式

这种结构的实现可以满足一定复杂度的运算符,我们刚刚接触栈的时候都会自己实现以下这种表达式的运算方式。

本篇博客要介绍的是另外一种实现这种表达式计算的方法----使用表达式树

首先来介绍以下什么是表达式树:

    表达式树是一棵树,他是对一个字符串形式的表达式的树形表示。图1是一个表达式树的例子(图片来自网络),从图片上可以看出,表达式的树形表示很容易计算结果,一棵表达式树的结果可以使用递归的方法很方便的求解出,看求解函数:

 

    private double getValue(Node root) throws Exception{
        if(root == null) throw new Exception("解析表达式出现异常");
        switch(root.op){
        case '+':
            return getValue(root.left)+getValue(root.right);
        case '-':
            return getValue(root.left)-getValue(root.right);
        case '*':
            return getValue(root.left)*getValue(root.right);
        case '/':
            return getValue(root.left)/getValue(root.right);
        case '\0':
            return root.val;
        default:
            throw new Exception("目前还不支持 "+root.op" 运算符。")
        }
    }
求解表达式树的结果

 

有上述代码可以看出,对于表达式树的求解可以说是很容易,程序容易写也容易理解。那么如何生成一棵表达式树呢?这是本篇博客的重点内容。

首先来看一下对于这个表达式,如何生成表达式树:2+3-4-1+5 这个表达式只含有+和-两种操作,程序操作流程如下:

1,读取一个数 2

2,读取一个操作符 +,将该数作为该操作符的左元素,如果读取不到退出

3,读取一个操作数 3,将该数作为该操作符的右操作数。

4,将该操作数节点作为一个数,回到2

经过以上操作,可以达到一棵表达式树:

 

现在我们考虑*/的情况,相比+-,*/是一种优先级更高的操作数 ::2+3*4-1+5

 

posted @ 2017-04-13 14:39  gukz  阅读(1242)  评论(0编辑  收藏  举报