c++ 实现数学表达式解析
来源:互联网 发布:电话薄软件 编辑:程序博客网 时间:2024/06/06 17:32
在最近的项目中希望使用一个简单的表达式计算功能, 网上有开源的库,但是体积庞大,编译链接缓慢。
所以最后还是自己实现了一个。 支持几乎所有的数学运算符, 以及<cmath> 内置的函数。
实现原理简述:
c++实现表达式计算的思路一般有两种, (此处使用的是后者。)
1. 使用面向对象的多态特性, 对每一种运算符实现一个表达式类, 类似
class Exp;
class AddExp:Exp;
class MulExp:Exp;
....
虚拟重载evaluate()求值函数, 在解析表达式的过程中构建一颗表达式树,同时根据运算符优先级对树做旋转。
2. 基于堆栈
使用两个栈 O 和 N, 一个存算符, 一个存操作数, 根据算符优先级出入栈。
线性扫描表达式, 比较当前算符 和栈顶算符的优先级(还要考虑结合性),如果后者优先级高, 则从数值栈顶取出元素并计算,然后把返回值入栈。
否则 操作符/操作数依次入栈
实例: 计算 1*2+3 具体过程
依次入栈
push 1; push *; push 2
此时栈内元素如下, 下一个算符为'+'
N |1|2|
O |*|
由于栈顶端算符为*, 优先级高于+, 所以先计算*, 从数值栈顶取出两个操作数1和2, 相乘得返回值2,入栈
pop 1; pop 2; pop *; push 1*2
N |2|
O |
然后再处理后面的‘+’
N |2|3|
O |+|
-->
N |5|
O |
大致思路如上述
3. 实现
所以最后还是自己实现了一个。 支持几乎所有的数学运算符, 以及<cmath> 内置的函数。
实现原理简述:
c++实现表达式计算的思路一般有两种, (此处使用的是后者。)
1. 使用面向对象的多态特性, 对每一种运算符实现一个表达式类, 类似
class Exp;
class AddExp:Exp;
class MulExp:Exp;
....
虚拟重载evaluate()求值函数, 在解析表达式的过程中构建一颗表达式树,同时根据运算符优先级对树做旋转。
2. 基于堆栈
使用两个栈 O 和 N, 一个存算符, 一个存操作数, 根据算符优先级出入栈。
线性扫描表达式, 比较当前算符 和栈顶算符的优先级(还要考虑结合性),如果后者优先级高, 则从数值栈顶取出元素并计算,然后把返回值入栈。
否则 操作符/操作数依次入栈
实例: 计算 1*2+3 具体过程
依次入栈
push 1; push *; push 2
此时栈内元素如下, 下一个算符为'+'
N |1|2|
O |*|
由于栈顶端算符为*, 优先级高于+, 所以先计算*, 从数值栈顶取出两个操作数1和2, 相乘得返回值2,入栈
pop 1; pop 2; pop *; push 1*2
N |2|
O |
然后再处理后面的‘+’
N |2|3|
O |+|
-->
N |5|
O |
大致思路如上述
3. 实现
1. 实现一个函数 tokenize 把表达式拆解为一个一个独立的token 忽略空格等
此处的token指 数值/算符/变量
2. 实现一个函数evaluate 根据上述原理扫描已经过预处理的token序列, 实现计算。
3.对左值的处理也考虑了, 具体见源码。代码见资源。
http://download.csdn.net/detail/tiankong_bear/9668171
更正:
上面的代码里面有一个bug
line 400 开始应该改为
if (RPAR == it->opr) {
if (prevOp != LPAR) {throw ExprError("parenthese unmatch");}
sOpr.pop();
} else {
sOpr.push(it->opr);
}
否则会有括号匹配问题。
资源代码 已更正。
1 0
- c++ 实现数学表达式解析
- 解析数学表达式
- 解析数学表达式
- c计算数学表达式
- 数学表达式解析-JAVA版
- 数学表达式解析器简介
- c实现极简单的正则表达式解析
- 数学表达式计算(汇编实现)
- 通过入栈出栈实现数学表达式的计算
- java实现数学表达式的运算(Stack)
- 表达式解析的(C#)源码
- C指针解析 ------ 指针表达式
- c实现表达式求值
- 某一天的思考题(解析数学表达式)的参考答案
- muParser—快速的数学表达式解析器库
- PyQt5学习教程12:数学表达式解析程序
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)
- android中view使用背景shape显示不出圆角
- QQ企业邮箱设置IMAP、POP3/SMTP及其SSL加密方式
- Tempter of the Bone (深搜+剪枝)
- Javascript笔记
- 初识无人机
- c++ 实现数学表达式解析
- C语言求二进制中1的个数
- C语言求10个数中的最大数
- Servlet,MVC模型,Web监听器--14
- MTKLogger中main_log.boot和main_log区别
- java国际化IDEA控制台乱码问题
- C语言交换两个数的值
- 如何从官方渠道下载Spring MVC所需jar包
- C++的运算符重载