表达式求值(栈方法/C++语言描述)(一)
一个算数表达式(以下简称为表达式)由运算数、运算符、左括号和右括号组成,定义一个枚举类型TokenType表示为:
1 typedef enum { 2 BEGIN, 3 NUMBER, 4 OPERATOR, 5 LEFT_BRAC, 6 RIGHT_BRAC 7 } TokenType;
BEGIN用来表示表达式的开始,稍后会再提及到它。
对表达式进行求值需要借助数据结构栈,C++的标准模板库中包含stack类型,只需要包含头文件stack并引用命名空间std就可以使用了。整个求值过程总共需要2个栈,分别用来存储运算数和运算符;基本求值过程是这样的:比较当前运算符和运算符栈中栈顶运算符的优先级,若栈顶运算符优先级高于当前运算符,则从运算数栈中弹出两个运算数,使用运算符栈栈顶运算符进行计算后再压入运算数栈,并将当前运算符压入运算符栈,否则只将当前运算符压入运算符栈;最后反复上述运算压栈过程直至运算符栈为空,运算数栈的栈顶元素即为运算结果。Calculator类声明如下:
1 class Calculator 2 { 3 public: 4 double calculate(string expression) throw(string); 5 6 private: 7 stack<double> _stkNumbers; 8 stack<char> _stkOperators; 9 10 static int priority(char op); 11 static double calculate(double d1, char op, double d2) throw(string); 12 13 void calculateStack() throw(string); 14 void dealWithNumber(char *&pToken) throw(string); 15 void dealWithOperator(char *&pToken) throw(string); 16 void dealWithLeftBrac(char *&pToken) throw(string); 17 void dealWithRightBrac(char *&pToken) throw(string); 18 };
使用代码描述的运算压栈过程如下:
1 void Calculator::calculateStack() throw (string) { 2 double d2 = _stkNumbers.top(); 3 _stkNumbers.pop(); 4 double d1 = _stkNumbers.top(); 5 _stkNumbers.pop(); 6 char op = _stkOperators.top(); 7 _stkOperators.pop(); 8 _stkNumbers.push(calculate(d1, op, d2)); 9 }
静态成员函数calculate()用于进行简单的四则运算,同时也处理了除数为0的情况:
1 double Calculator::calculate(double d1, char op, double d2) throw (string) { 2 assert(op == '+' || op == '-' || op == '*' || op == '/'); 3 4 cout << d1 << op << d2 << endl; 5 6 if (op == '+') { 7 return d1 + d2; 8 } else if (op == '-') { 9 return d1 - d2; 10 } else if (op == '*') { 11 return d1 * d2; 12 } else { 13 if (!d2) { 14 throw string("divided by 0"); 15 } 16 return d1 / d2; 17 } 18 }
此外,根据数学规则,有:
- 表达式只能以左括号或运算数开始;
- 运算数后只能是右括号或运算符;
- 运算符或左括号后只能是左括号或运算数;
- 右括号后只能是另一个右括号或运算符。
使用代码描述这些数学规则和最后清空运算符栈的过程如下:
1 double Calculator::calculate(string expression) throw (string) { 2 while (!_stkNumbers.empty()) { 3 _stkNumbers.pop(); 4 } 5 while (!_stkOperators.empty()) { 6 _stkOperators.pop(); 7 } 8 TokenType lastToken = BEGIN; 9 10 char * pToken = &expression[0]; 11 while (*pToken) { 12 switch (lastToken) { 13 case BEGIN: 14 if (*pToken == '(') { 15 // an expression begin with a left bracket 16 dealWithLeftBrac(pToken); 17 lastToken = LEFT_BRAC; 18 } else { 19 // or a number 20 dealWithNumber(pToken); 21 lastToken = NUMBER; 22 } 23 break; 24 case NUMBER: 25 // after a number 26 if (*pToken == ')') { 27 // it may be a right bracket 28 dealWithRightBrac(pToken); 29 lastToken = RIGHT_BRAC; 30 } else { 31 // it may be an operator 32 dealWithOperator(pToken); 33 lastToken = OPERATOR; 34 } 35 break; 36 case OPERATOR: 37 case LEFT_BRAC: 38 // after an operator or a left bracket 39 if (*pToken == '(') { 40 // it may be a left bracket 41 dealWithLeftBrac(pToken); 42 lastToken = LEFT_BRAC; 43 } else { 44 // it may be a number 45 dealWithNumber(pToken); 46 lastToken = NUMBER; 47 } 48 break; 49 case RIGHT_BRAC: 50 // after a right bracket 51 if (*pToken == ')') { 52 // it may be another right bracket 53 dealWithRightBrac(pToken); 54 lastToken = RIGHT_BRAC; 55 } else { 56 // it may be an operator 57 dealWithOperator(pToken); 58 lastToken = OPERATOR; 59 } 60 break; 61 } 62 } 63 64 while (!_stkOperators.empty()) { 65 if (_stkOperators.top() == '(') { 66 throw string("bad token '('"); 67 } 68 calculateStack(); 69 } 70 71 assert(!_stkNumbers.empty()); 72 return _stkNumbers.top(); 73 }
lastToken用来指示上一个token的类型,它应该被初始化为BEGIN;在开始求值之前清空运算符栈和运算数栈,可以防止出错,是很有必要的。
转载于:https://www.cnblogs.com/lets-blu/p/7265961.html
表达式求值(栈方法/C++语言描述)(一)相关推荐
- c语言编程实现表达式求值,c语言实现表达式求值的方法
c语言实现表达式求值的方法 发布时间:2020-06-22 16:45:46 来源:亿速云 阅读:82 作者:Leah 这期内容当中小编将会给大家带来有关c语言实现表达式求值的方法,以专业的角度为大家 ...
- c语言作业算术表达式求值,算术表达式求值演示(C语言版)
//头文件预处理命令 #include #include //----------函数结果状态代码----------------- #define TRUE 1 #define FALSE 0 #d ...
- 7-10 逆波兰表达式求值 (20 分)(c语言)(数据结构)
逆波兰表示法是一种将运算符(operator)写在操作数(operand)后面的描述程序(算式)的方法.举个例子,我们平常用中缀表示法描述的算式(1 + 2)*(5 + 4),改为逆波兰表示法之后则是 ...
- 2015 UESTC 数据结构专题N题 秋实大哥搞算数 表达式求值/栈
秋实大哥搞算数 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1074 Des ...
- c语言求不定式的最大值,C语言之四则运算表达式求值(链栈)—支持浮点型数据,负数, 整型数据运算...
运算符间的优先级关系: 链栈结构体定义: 数据域使用字符串长度为20的字符数组(故需要注意判断读取的字符串是运算符还是数值) 可支持浮点型数据,负数, 整型数据的运算 float EvaluateEx ...
- c语言表达式的算法,表达式求值--数据结构C语言算法实现
这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...
- 九、表达式求值(1)
九.表达式求值(1) 文章目录 九.表达式求值(1) 题目描述 解题思路 上机代码 题目描述 背景: 我们的教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括: ...
- 牛客题霸 [表达式求值] C++题解/答案
牛客题霸 [表达式求值] C++题解/答案 题目描述 请写一个整数计算器,支持加减乘三种运算和括号. 题解: 没有除法emmm 我们从头开始依次判断每个字符 如果是左括号,我们就找右括号,并截取括号内 ...
- 表达式求值(最详细分析+代码实现+表达式之间的相互转换)
目录 一.概念 二.前缀表达式的逻辑和实现方式 1.定义 2.前缀表达式的计算机求值 3.例子 4.代码实现 三.中缀表达式的逻辑和实现方式 1.定义 2.中缀表达式规则 3.中缀表达式的计算机求值 ...
- python前缀表达式求值_python数据结构与算法 11 后缀表达式求值
从本节开始,删除原版的英文,直接发译后的文稿. 后缀表达式求值 栈的最一个应用例子,计算一个后缀表达式的值.这个例子中仍然用栈的数据结构.不过,当扫描表达式的时候,这次是操作数压栈等待,不是转换算法中 ...
最新文章
- 年薪 50w,这门编程语言该怎么学?
- java容器类的继承结构
- 按不同vlan下发dhcp_电脑网络:交换机VLAN基础知识及基本划分方法,揭开VLAN的面纱...
- 第三章:lambda表达式
- 分布式理论:CAP是三选二吗?
- java 异常处理 简书_Java基础知识8-异常处理
- python如何移动图片_Pygame的图像移动|python基础教程|python入门|python教程
- php serv-u,用php写的serv-u的web申请账号的程序_php
- Oracle 远程 RAC 打造双活数据中心 | 从容灾迈向双活案例分享
- 寺库商用区块链落地,联盟链为每件奢侈品发“×××”
- 【11月29】PF 粒子滤波的多维运动模型代码
- 关于一元线性回归、自相关性与Stata实现
- 基于STM32的红外万能遥控器完整教程
- 常用编程语言应用、前景及学习方法
- Hyperledger Fabric Service Discovery CLI(服务发现命令行工具)学习笔记
- python矩阵教程_Python Numpy Tutorial / Python Numpy 教程 (矩阵和图像操作)
- NuttX的学习笔记 9
- 计算机与航空方向专业,2018航空航天工程专业就业前景和就业方向分析
- 怎么把.txt转换成html,怎么把txt转换成HTML
- 默纳克调试说明书_默纳克NICE调试说明书修改版
热门文章
- mysql悲观锁优化_MySQL事务及实现、隔离级别及锁与优化
- python开发怎么成长_Python开发者四大进阶攻略,菜鸟的成神之路
- python语言是二进制语言吗_在大型项目上,Python 是个烂语言吗?
- C++ multimap 用法总结 例子
- Fisco bcos 在多机器上搭建多个节点的区块链网络 教程
- FISCO BCOS Solidity 使用Table合约CRUD接口 智能合约例子
- 计算机论文-中国免费,计算机硕士毕业论文免费
- linux启动hbase_HBase集群环境配置
- 远程连接linux主机_Linux远程桌面连接Windows
- JavaSE基础———StringBuffer StringBuilder Arrays和基本数据类型包装类