表达式求值(二叉树方法/C++语言描述)(三)

  二叉树方法求值对运算数处理的方法与栈方法求值不太相同,除了将字符串中的运算数转换为浮点类型外,还需要生成新的节点:

 1 void Calculator::dealWithNumber(char *&pToken) throw(string)
 2 {
 3     if (!isdigit(*pToken) && *pToken != ‘-‘)
 4     {
 5         throw string("bad token ‘") + *pToken + "‘";
 6     }
 7
 8     BinaryTreeNode<Token> * node = new BinaryTreeNode<Token>();
 9     assert(node);
10     node->_data._type = NUMBER;
11     node->_data._data.num = strtod(pToken, &pToken);
12     node->_leftChild = node->_rightChild = nullptr;
13     _stkNodes.push(node);
14 }

  对其他token的处理则和栈方法求值类似,请参考代码清单,这里不再赘述。

  公有方法calculate()直接调用了postOrder()方法,调用前清空用于存储浮点类型的栈,方法返回后这个栈的栈顶元素即为运算结果:

double Calculator::calculate()
{
    while (!_stkNumbers.empty())
    {
        _stkNumbers.pop();
    }

    BinaryTree::postOrder();

    assert(!_stkNumbers.empty());
    return _stkNumbers.top();
}

  postOrder()方法重写了从BinaryTree类继承的postOrder()方法,它在后序遍历时遇到运算数则压栈,遇到运算符则弹栈计算:

 1 void Calculator::postOrder(BinaryTreeNode<Token> *node)
 2 {
 3     if (node)
 4     {
 5         postOrder(node->_leftChild);
 6         postOrder(node->_rightChild);
 7         // visit binary tree data
 8         if (node->_data._type == NUMBER)
 9         {
10             _stkNumbers.push(node->_data._data.num);
11         }
12         else
13         {
14             assert(!_stkNumbers.empty());
15             double d2 = _stkNumbers.top();
16             _stkNumbers.pop();
17             assert(!_stkNumbers.empty());
18             double d1 = _stkNumbers.top();
19             _stkNumbers.pop();
20             char op = node->_data._data.op;
21             _stkNumbers.push(calculate(d1, op, d2));
22         }
23     }
24 }

静态方法calculate()与栈方法求值中的也相同。

  最后编写主函数,大功告成!

时间: 2024-08-24 14:16:00

表达式求值(二叉树方法/C++语言描述)(三)的相关文章

表达式求值(二叉树方法/C++语言描述)(二)

表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法中一样的枚举类型TokenType: 1 typedef enum 2 { 3 BEGIN, 4 NUMBER, 5 OPERATOR, 6 LEFT_BRAC, 7 RIGHT_BRAC 8 } TokenType; 9 10 class Token 11 { 12 public: 13 TokenType _type; 14 union 15 { 16 c

表达式求值(二叉树方法/C++语言描述)(五)

本例中的二叉树图是使用Graphviz绘制的(Graphviz官网),在Ubuntu Linux下可以使用apt-get命令安装它: 1 sudo apt-get install graphviz 表达式"1+2*3"和"1*2+3"的Dot代码如下: 1 # exp1_3.dot 2 digraph G{ 3 1 4 2 5 3 6 "*" -> 2 7 "*" -> 3 8 "+" ->

表达式求值(二叉树方法/C++语言描述)(四)

代码清单 1 // binarytree.h 2 #ifndef BINARYTREE_H 3 #define BINARYTREE_H 4 5 template <typename T> class BinaryTree; 6 7 template <typename T> 8 class BinaryTreeNode 9 { 10 public: 11 friend class BinaryTree<T>; 12 friend class Calculator; 1

使用逆波兰式进行表达式求值

中缀表达式及后缀表达式图解中说明了使用逆波兰式进行表达式求值的方法,这里使用C++进行实现.实现和原理讲解有一点不同,需要进一步进行细化. 关于将中缀表达式转换成后后缀表达式的规则: 规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分:若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止. 上面的规则转换成下面的执行规则: 1.遇到操作数:直接输出(添加到后缀

LeetCode:逆波兰表达式求值【150】

LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说,表达式总会得出有效数值且不存在除数为 0 的情况. 示例 1: 输入: ["2", "1", "+", "3", "*"] 输出: 9 解释: ((2

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

序列点在C语言表达式求值中的作用

摘要: 本文开创性地分析了序列点在C语言表达式求值中的作用:序列点左边的操作数要先于其右边的操作数求值.讨论了逗号操作符,.逻辑与操作符&&.逻辑或操作符||和条件操作符?:的问号处需要序列点的原因.举例分析了序列点在表达式求值中的作用. 关键字:序列点 表达式求值 C语言 C语言作为一种主流程序设计语言,许多编程语言如Java.C++.C#都借鉴了它的语法.C语言也是一种很适当的程序设计入门的教学语言,国内大专院校的许多专业都开设了这门课程并且大多将其作为第一门程序设计语言课程,同时C语

C/C++ 语言中的表达式求值

蛱酝缒 C/C++ 语言中的表达式求值

一起talk C栗子吧(第二十一回:C语言实例--表达式求值)

各位看官们,大家好,前几回中咱们说了堆栈的原理,并且举了实际的例子进行解说,这一回咱们说的例 子是:表达式求值.表达式求值和上一回中说的括号匹配一样,都使用了堆栈的原理,大家可以从例子中 看出来,所以我们把它们放在一起.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在这里说的表达式为包含加,减,乘除的四则运算表达式.例如:1+2*3-4/5就是一个四则运 算表达式.这个表达式中,运算符在数字中间,所以我们叫它中缀表达式,这也是符合我们思维的一种表 现形式,不过,计算机就不理解中