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

 void Calculator::dealWithNumber(char *&pToken) throw(string)
{
if (!isdigit(*pToken) && *pToken != '-')
{
throw string("bad token '") + *pToken + "'";
} BinaryTreeNode<Token> * node = new BinaryTreeNode<Token>();
assert(node);
node->_data._type = NUMBER;
node->_data._data.num = strtod(pToken, &pToken);
node->_leftChild = node->_rightChild = nullptr;
_stkNodes.push(node);
}

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

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

 double Calculator::calculate()
{
while (!_stkNumbers.empty())
{
_stkNumbers.pop();
} BinaryTree::postOrder(); assert(!_stkNumbers.empty());
return _stkNumbers.top();
}

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

 void Calculator::postOrder(BinaryTreeNode<Token> *node)
{
if (node)
{
postOrder(node->_leftChild);
postOrder(node->_rightChild);
// visit binary tree data
if (node->_data._type == NUMBER)
{
_stkNumbers.push(node->_data._data.num);
}
else
{
assert(!_stkNumbers.empty());
double d2 = _stkNumbers.top();
_stkNumbers.pop();
assert(!_stkNumbers.empty());
double d1 = _stkNumbers.top();
_stkNumbers.pop();
char op = node->_data._data.op;
_stkNumbers.push(calculate(d1, op, d2));
}
}
}

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

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

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

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

    表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法求值中一样的枚举类型TokenType: typedef en ...

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

    使用二叉树对算数表达式(以下简称为表达式)进行求值,实质上是将表达式转换为二叉树,对其进行后序遍历,得到后缀表达式的同时可以求得表达式的值.转换和求值的过程也需要借助数据结构栈的帮助. 二叉树数据结构 ...

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

    本例中的二叉树图是使用Graphviz绘制的(Graphviz官网),在Ubuntu Linux下可以使用apt-get命令安装它: sudo apt-get install graphviz 表达式 ...

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

    代码清单 // binarytree.h #ifndef BINARYTREE_H #define BINARYTREE_H template <typename T> class Bin ...

  5. 表达式求值--数据结构C语言算法实现

    这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...

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

    LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...

  7. 表达式求值(栈方法/C++语言描述)(二)

    上篇中完成了对表达式求值的整体过程,接下来看看如何处理不同类型的token. 对运算数的处理比较简单,它直接调用函数strtod(),将字符串中的运算数转换为浮点类型并将它压入运算数栈中: void ...

  8. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  9. Java描述表达式求值的两种解法:双栈结构和二叉树

    Java描述表达式求值的两种解法:双栈结构和二叉树 原题大意:表达式求值 求一个非负整数四则混合运算且含嵌套括号表达式的值.如: # 输入: 1+2*(6/2)-4 # 输出: 3.0 数据保证: 保 ...

随机推荐

  1. epoll的ET和LT模式比较 - 源码分析

    eventpoll是一种文件,它实现了一种机制利用一条rdllist队列来避免阻塞地进行poll.eventpoll归根到底还是在使用poll.而ET比LT高效,并不在于是否使用了poll,更不能说是 ...

  2. App测试札记

    App测试札记 测试应该收集信息 测试应该问问题 测试应该扮演不同角色 测试应该如实反馈 初学者 有哪些可以利用的信息?需求,技术方案,测试设计,现有功能,相关人员 App会在哪些环境下运行 App会 ...

  3. redmine测试使用小结

    在尽量不影响当前项目活动的情况下,可以对测试过程作部分改进,能够支持建立项目的BUG管理过程,简述如下: 1.配置角色和权限->新建角色:测试人员 (1)主要配置问题跟踪权限 (2)提前规划好再 ...

  4. 推荐几个Dynamic Crm的大神博客

    ghostbear的博客:http://blog.csdn.net/ghostbear/article/category/1072859 ghostbear大神的博客是新手学习Dynamics Crm ...

  5. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

  6. 避免循环做SQL操作

    经常犯的错误是把一个SQL 操作放置到一个循环中, 这就导致频繁的访问数据库,更重要的是, 这会直接导致脚本的性能低下.以下的例子, 你能够把一个循环操作重置为一个单一的SQL语句. foreach ...

  7. javac不是内部命令和外部命令

    因为系统不能识别javac命令,或者是因为你没有正确安装JDK. 在你的JDK所在的安装目录,在DOS环境里,比如是:C:\java>set path=c:\java1.4.1\bin 然后在c ...

  8. MySQL删除表方式差异

    数据库删除语句 Drop/Delete/Truncate比较 Delete :删除数据表中的行(可以删除某一行,也可以在不删除数据表的情况下删除所有行). 删除某一行:Delete from 数据表名 ...

  9. 【jframe】Java Web应用程序框架 - 第01篇:Get Started

    jframe是什么? jframe是一个基于MIT协议开源的java web应用程序框架,汇聚了我们团队之于java web应用程序的核心架构思想以及大量最佳实践,并且持续在实际项目中不断完善优化. ...

  10. KBEngine简单RPG-Demo源码解析(3)

    十四:在世界中投放NPC/MonsterSpace的cell创建完毕之后, 引擎会调用base上的Space实体, 告知已经获得了cell(onGetCell),那么我们确认cell部分创建好了之后就 ...