表达式求值(栈方法/C++语言描述)(三)
代码清单
// calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H #include <stack>
#include <string>
#include <iostream>
#include <cassert> using namespace std; typedef enum {
BEGIN,
NUMBER,
OPERATOR,
LEFT_BRAC,
RIGHT_BRAC
} TokenType; class Calculator
{
public:
double calculate(string expression) throw(string); private:
stack<double> _stkNumbers;
stack<char> _stkOperators; static int priority(char op);
static double calculate(double d1, char op, double d2) throw(string); void calculateStack() throw(string);
void dealWithNumber(char *&pToken) throw(string);
void dealWithOperator(char *&pToken) throw(string);
void dealWithLeftBrac(char *&pToken) throw(string);
void dealWithRightBrac(char *&pToken) throw(string);
}; #endif // CALCULATOR_H // calculator.cpp
#include "calculator.h" int Calculator::priority(char op) {
assert(op == '+' || op == '-' || op == '*' || op == '/' || op == '('); if (op == '+' || op == '-') {
return ;
} else if (op == '*' || op == '/') {
return ;
} else {
return ;
}
} double Calculator::calculate(double d1, char op, double d2) throw (string) {
assert(op == '+' || op == '-' || op == '*' || op == '/'); cout << d1 << op << d2 << endl; if (op == '+') {
return d1 + d2;
} else if (op == '-') {
return d1 - d2;
} else if (op == '*') {
return d1 * d2;
} else {
if (!d2) {
throw string("divided by 0");
}
return d1 / d2;
}
} void Calculator::calculateStack() throw (string) {
double d2 = _stkNumbers.top();
_stkNumbers.pop();
double d1 = _stkNumbers.top();
_stkNumbers.pop();
char op = _stkOperators.top();
_stkOperators.pop();
_stkNumbers.push(calculate(d1, op, d2));
} double Calculator::calculate(string expression) throw (string) {
while (!_stkNumbers.empty()) {
_stkNumbers.pop();
}
while (!_stkOperators.empty()) {
_stkOperators.pop();
}
TokenType lastToken = BEGIN; char * pToken = &expression[];
while (*pToken) {
switch (lastToken) {
case BEGIN:
if (*pToken == '(') {
// an expression begin with a left bracket
dealWithLeftBrac(pToken);
lastToken = LEFT_BRAC;
} else {
// or a number
dealWithNumber(pToken);
lastToken = NUMBER;
}
break;
case NUMBER:
// after a number
if (*pToken == ')') {
// it may be a right bracket
dealWithRightBrac(pToken);
lastToken = RIGHT_BRAC;
} else {
// it may be an operator
dealWithOperator(pToken);
lastToken = OPERATOR;
}
break;
case OPERATOR:
case LEFT_BRAC:
// after an operator or a left bracket
if (*pToken == '(') {
// it may be a left bracket
dealWithLeftBrac(pToken);
lastToken = LEFT_BRAC;
} else {
// it may be a number
dealWithNumber(pToken);
lastToken = NUMBER;
}
break;
case RIGHT_BRAC:
// after a right bracket
if (*pToken == ')') {
// it may be another right bracket
dealWithRightBrac(pToken);
lastToken = RIGHT_BRAC;
} else {
// it may be an operator
dealWithOperator(pToken);
lastToken = OPERATOR;
}
break;
}
} while (!_stkOperators.empty()) {
if (_stkOperators.top() == '(') {
throw string("bad token '('");
}
calculateStack();
} assert(!_stkNumbers.empty());
return _stkNumbers.top();
} void Calculator::dealWithNumber(char *&pToken) throw (string) {
if (!isdigit(*pToken) && *pToken != '-') {
throw string("bad token '") + *pToken + "'";
}
_stkNumbers.push(strtod(pToken, &pToken));
} void Calculator::dealWithOperator(char *&pToken) throw (string) {
if (*pToken != '+' && *pToken != '-' && *pToken != '*' && *pToken != '/') {
throw string("bad token '") + *pToken + "'";
}
if (!_stkOperators.empty()
&& priority(_stkOperators.top()) >= priority(*pToken)) {
calculateStack();
}
_stkOperators.push(*pToken);
pToken++;
} void Calculator::dealWithLeftBrac(char *&pToken) throw (string) {
if (*pToken != '(') {
throw string("bad token '") + *pToken + "'";
}
_stkOperators.push(*pToken);
pToken++;
} void Calculator::dealWithRightBrac(char *&pToken) throw (string) {
if (*pToken != ')') {
throw string("bad token '") + *pToken + "'";
}
while (!_stkOperators.empty() && _stkOperators.top() != '(') {
calculateStack();
if (_stkOperators.empty()) {
throw string("bad token ')'");
}
}
_stkOperators.pop();
pToken++;
} // main.cpp
#include "calculator.h" int main(int argc, char *argv[])
{
Calculator calculator; if (argc > ) {
if (argc == ) {
cout << calculator.calculate(string(argv[])) << endl;
} else {
cout << "too many arguments" << endl;
return -;
}
} else {
while () {
string expression;
cout << ">" << flush;
cin >> expression;
if (expression == "quit;") {
cout << "Bye." << endl;
return ;
}
try {
cout << calculator.calculate(expression) << endl;
} catch (string ex) {
cout << ex << endl;
}
}
}
}
表达式求值(栈方法/C++语言描述)(三)的更多相关文章
- 表达式求值(栈方法/C++语言描述)(二)
上篇中完成了对表达式求值的整体过程,接下来看看如何处理不同类型的token. 对运算数的处理比较简单,它直接调用函数strtod(),将字符串中的运算数转换为浮点类型并将它压入运算数栈中: void ...
- 第四届河南省ACM 表达式求值 栈
表达式求值 时间限制: 1 Sec 内存限制: 128 MB 提交: 14 解决: 7 [提交][状态][讨论版] 题目描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简 ...
- 表达式求值 (栈) 用C++实现
#include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #incl ...
- Python解析 算数表达式求值 栈的使用
使用Python实现一种算数表达式求值的算法,模拟这种使用栈的方式,这是由E.W.Dijkstra在20世纪60年代发明的一种非常简单的算法.代码模拟仅仅表现一种编程思想,代码的逻辑并不完全: if ...
- 表达式求值(栈方法/C++语言描述)(一)
一个算数表达式(以下简称为表达式)由运算数.运算符.左括号和右括号组成,定义一个枚举类型TokenType表示为: typedef enum { BEGIN, NUMBER, OPERATOR, LE ...
- 2015 UESTC 数据结构专题N题 秋实大哥搞算数 表达式求值/栈
秋实大哥搞算数 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1074 Des ...
- 表达式求值--数据结构C语言算法实现
这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...
- LeetCode:逆波兰表达式求值【150】
LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
随机推荐
- VMware安装CentOS 提示:已将该虚拟机配置为使用 64 位客户机操作系统。但是,无法执行 64 位操作。解决方案
安装虚拟机遇到错误: 在网上查了查资料,发现CPU支持VT技术的就能支持vmware中安装64位虚拟机. 以下是操作步骤: 1)到网上下载一个securable.exe,测试以下机器是否支持VT. l ...
- 使用 Socket.IO 开发聊天室
前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...
- Java Web开发环境配置(JDK+Tomcat++IDEA 14)
对于未接触过java web开发的大家而言,应该和我一样对java web编程开发比较迷茫,通过查一些资料,大致清楚了java web开发环境的一些基本配置,未做过相关编程的人员可以看一看,由于我刚接 ...
- java如何LOG打印出日志信息
log4j 记录日志方式 log4j 是apache 提供的记录日志的jar 档. 下载路径: http://logging.apache.org/log4j/1.2/download.html 这里 ...
- (转载)VB6之鼠标移出事件
转载链接:http://www.ltesting.net/ceshi/ruanjianceshikaifajishu/rjcskfyy/vb/2007/0525/3426.html Windows提供 ...
- linux 配置Apache 、PHP
1. 安装 Apache 安装apache,首先要使用管理员权限,如果如法获取请联系您的管理员. centos: yum install httpd httpd-devel 2. 安装PHP 同样也需 ...
- CSS自定义动画
动画名称 animation-name : (动画名称必须与@keyfarmes的名称相对应,因为动画名称是由@keyfarmes定义的) 例如:animation-name:AA:则 @ ...
- 解决window7 x64位Anaconda启动报错:AttributeError: '_NamespacePath' object has no attribute 'sort'
最近论文需要用到python做数据分析,python语法简单,但是Windows下安装第三方包恶心的要命,statsmodels用pip死活安装不上,网上查了说包相互依赖windows下的pip不能下 ...
- js如何获取样式?
在某个项目中,我们经常会需要来获取某个元素的样式,比如说获取一个div的color:这样,新的问出现了, var style = box.style.width;console.log(style); ...
- [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增
Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...