C++表达式求值(利用数据结构栈)
唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行。这不经让我
想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的表
达式)的简单计算器程序。刚把两个程序对照了一下。感触还是挺深的,同一时候也再一次体现了数据结构在程序设计
中的重要性。
曾经的那个程序有漏洞并且逻辑复杂,所以就不提了,仅仅说说如今改进后的程序,其思想主要是用到了
栈先进后出的数据结构。在该程序中建有两个栈:一个用于存储运算符,还有一个用于存储操作数或运算结果。基本
过程是:
(1):首先设置操作数栈为空栈,设置运算符栈以‘#’为栈底元素(其优先级最低)。
(2):通过为栈内栈外运算符设置值而比較其优先级
(3):依次去找到表达式中的全部运算符和操作数,对于操作数直接入栈。运算符则和运算符栈的
栈顶运算进行比較优先级,若栈内优先级大,则进行对应操作并操作数和栈内运算符都出栈,若优先级相等仅仅需
栈内运算符出栈继续查找下一个运算符就可以,若栈内优先级低则栈外运算符入栈。依次循环知道分析完表达式中
的全部运算符和操作数就可以。
(4):最后在操作数栈中将仅仅会剩下唯一的一个元素,而该元素也将就会是所求表达式的值。
#include<iostream>
#include<stack>
#include<string>
using namespace std; /*推断符号间的优先关系函数
*1表示>,0表示=,-1表示<
*c1栈内的算符。c2栈外的算符
*/
int Judge(char c1,char c2)
{
int a1,a2;
if('+'==c1||'-'==c1) a1 = 3;
if('*'==c1||'/'==c1)a1 = 5;
if('('==c1) a1 = 1;
if(')'==c1) a1 = 7;
if('#'==c1) a1 = 0; if('+'==c2||'-'==c2)a2 = 2;
if('*'==c2||'/'==c2)a2 = 4;
if('('==c2) a2 = 6;
if(')'==c2) a2 = 1;
if('#'==c2) a2 = 0;
if(a1>a2) return 1;
if(a1==a2) return 0;
if(a1<a2) return -1;
}
//符号运算函数
double run(char c ,double d1,double d2)
{
switch (c)
{
case '+':
return d1+d2;
break;
case '-':
return d1-d2;
break;
case'*' :
return d1*d2;
break;
case '/':
return d1/d2;
break;
default:
return 0.0;
break;
}
}
int main()
{
char * op = "+-*/()#";
string str ;
cin>>str;
//给表达式字符串str加入'#'结束标识符
str.append(1,'#');
stack<char> OPTR;//运算符栈
stack<double> OPND;//操作数栈
int a = -1;
//先将#符号入栈
OPTR.push('#');
while(true)
{
int b = a+1;
a = str.find_first_of(op,a+1);
if(a==string::npos) break;
if(a!=b)
{
string ss(str,b,a-b);
double d=atof(ss.c_str());
//数据先入栈
OPND.push(d);
}
//运算符优先级比較
int ju = Judge(OPTR.top(),str[a]);
if(-1==ju)//栈外优先级大直接入栈
{
OPTR.push(str[a]);
}
if(0==ju)//栈内外优先级相等则出栈
{
OPTR.pop();
}
if(1==ju)//栈内优先级大,出栈进行运算
{
double d1 = OPND.top();
OPND.pop();
double d2 = OPND.top();
OPND.pop();
d1 = run(OPTR.top(),d2,d1);
//运算结果入栈
OPND.push(d1);
OPTR.pop();
a--;
}
}
//删除表达式最后的'#'结束标识符
str.erase(str.length()-1,1);
cout<<str<<" = "<<OPND.top()<<endl;
}
C++表达式求值(利用数据结构栈)的更多相关文章
- 【TOJ 4309】表达式求值(模拟栈)
Description Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经 ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值
一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...
- 数据结构--栈的应用(表达式求值 nyoj 35)
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...
- 数据结构课程设计四则运算表达式求值(C语言版)
本系统为四则运算表达式求值系统,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值.注意事项: 1.请保证输入的四则表达式的合法性.输入的中缀表达式中只能含有英文符号"+ ...
- 刁肥宅详解中缀表达式求值问题:C++实现顺序/链栈解决
1. 表达式的种类 如何将表达式翻译成能够正确求值的指令序列,是语言处理程序要解决的基本问题,作为栈的应用事例,下面介绍表达式的求值过程. 任何一个表达式都是由操作数(亦称运算对象).操作符(亦称运算 ...
- 表达式求值--数据结构C语言算法实现
这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...
- 【NYOJ-35】表达式求值——简单栈练习
表达式求值 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...
- 表达式求值 (栈) 用C++实现
#include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #incl ...
随机推荐
- [JavaEE] Hibernate连接池配置测试
转载自51CTO http://developer.51cto.com/art/200906/129914.htm Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以 ...
- php手机号码验证正则表达式
移动:134.135.136.137.138.139.150.151.152.157.158.159.182.183.184.187.188.178(4G).147(上网卡): 联通:130.131. ...
- 实体类中方法名尽量避免set,get,报错com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException)
自己建了一个实体类 public class MissPoint implements Serializable{ private static final long serialVersionUID ...
- BZOJ 2140 Tarjan
思路: 跟POJ有一道时限挺长的题一模一样 哦 POJ 1904 题解可以看这个(捂脸) http://blog.csdn.net/qq_31785871/article/details/52963 ...
- Aspose.cell中的Excel模板导出数据
//Excel模板导数据(Eexcel中根据DataTable中的个数,给多个Sheet中的模板赋值) public void DataSetToManyExcel(string fileName, ...
- 创建一个netcore2.0和angular的项目并运行起来
netcore2.0发布了,喜大普奔. 我们先下载SDK,请看张善友老师的这篇博客 http://www.cnblogs.com/shanyou/p/7363037.html 下载完之后 我用的vs2 ...
- arttemplate.js原生写法案例
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Android stroke 边框线 某一边
有时候需要给View加边框线,我们经常是四边一起加,就像这样: <shape xmlns:android="http://schemas.android.com/apk/res/and ...
- 第八周读书笔记(人月神话X月亮与六便士)——到底什么才是一个程序员的自我修养?
写了这么久的读书笔记,涉及到问题大多是一些如何把软件工程做好,如何把自己的职业生涯做好.但总感觉逻辑链上缺了一环,亦即:我们为什么要把软件工程做好,我们成为一名优秀的职业生涯的意义到底在于什么?我觉得 ...
- 经典C/S服务器模型之守护进程
linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服务 ...