表达式求值(C语言)_c语言表达式计算_索儿呀的博客-程序员秘密

技术标签: C语言    表达式求值  数据结构  

代码可以实现的功能:

  • 可以计算任意正整型
  • 但是只可以进行 + - * / () 运算

我写的代码,
因为我想代码可以实现:表达式可以计算任意正整型数,所以定义了两个栈,分别用来存放操作符和操作数;
批注:如果只定义一个栈,我觉得我只能做到,我的代码只能计算0到9的表达式
因为定义了两个栈(存放不同类型的值,一个存放字符,一个存放数值),所以初始化,入栈,出栈,取栈顶元素的函数都要写两遍

然后核心就是,表达式的代码,要解决优先级的问题

再加个提醒吧:代码中出现的

  • TR:代表operater,即运算符:+ - * / ()
  • ND:代表operand,即操作数:整型的数值

哦,对了,还有一个血的教训,在控制台中输入表达式时,如果有(),必须用英文输入法输入(),不然,嘿嘿,心态爆炸

#include<iostream>
using namespace std;

#define starksize 100 
typedef struct{
    
	char *base;
	char *top;
	int length ;
}StarkTR; //寄存运算符

typedef struct{
    
	int *base;
	int *top;
	int length ;
}StarkND; //寄存操作数 
 
int InitTR(StarkTR &L){
       //初始化寄存operater栈 
	L.base = new char[starksize];
	L.top = L.base;
	L.length = starksize; 
	return 1;
}
int InitND(StarkND &L){
       //初始化寄存operand栈 
	L.base = new int[starksize];
	L.top = L.base;
	L.length = starksize; 
	return 1;
}

int PushTR(StarkTR &L,char e){
       //入栈 
	if(L.top - L.base == L.length){
    
		cout<<"栈满!";
		return 0; 
	}
	*L.top++ = e;
	return 1;
}
int PushND(StarkND &L,int e){
       //入栈 
	if(L.top - L.base == L.length){
    
		cout<<"栈满!";
		return 0; 
	}
	*L.top++ = e;
	return 1;
}

char PopTR(StarkTR &L,char &e){
       //出栈 
	if(L.top - L.base == 0){
    
		cout<<"栈空!";
		return 0;
	}
	e = *--L.top;
	return 1;
}
int PopND(StarkND &L,int &e){
       //出栈 
	if(L.top - L.base == 0){
    
		cout<<"栈空!";
		return 0;
	}
	e = *--L.top;
	return 1;
}

char GetTopTR(StarkTR L){
      //取栈顶元素 
	if(L.top != L.base)
		return *(L.top -1); 
}
int GetTopND(StarkND L){
      //取栈顶元素 
	if(L.top != L.base)
		return *(L.top -1); 
}

char Precede(char a,char b){
         //< > = 都代表优先级 
								 //只考虑 + - * / ( ) 的运算 
	if(a == '+'||a == '-'){
    
		if(b == '+'||b == '-'||b == ')'||b == '#')return '>';
		else return '<';
	}
	else if(a == '*'||a == '/'){
    
		if(b == '+'||b == '-'||b == ')'||b == '#'||b == '*'||b == '/')return '>';
		else return '<';
	}
	else if(a == '('){
    
		if(b == ')')return '=';
		else return '<';
	}
	else if(a == ')'){
    
		return '>';
	}
	else{
    
		if(b == '#')return '=';
		else return '<';
	}
}          

int Operate(int a,char s,int b){
    
	if(s == '+'){
    
		return a+b;
	}
	else if(s == '-'){
    
		return a-b;
	}
	else if(s == '*'){
    
		return a*b;
	}
	else if(s == '/'){
    
		return a/b;
	}
}


int EvaluateExpression(){
    
	StarkTR operater;
	StarkND operand;
	char ch,op;
	int t,k,a,b;
	InitTR(operater);
	InitND(operand);
	PushTR(operater, '#'); //将表达式起始符“#”压入operater栈中
	cout<<"please input a evaluate expression(以 # 结束,只能运算 + - * /):"<<endl;
	cin>>ch;
	while(ch != '#'||GetTopTR(operater) != '#'){
    
		t = 0;
		k = 0;
		while(ch <= '9'&&ch >= '0'){
    
			t = t*10 + (ch - 48);   //0的ASCLL码是48 
			cin>>ch; 
			k++;
		}
		if(k)PushND(operand,t);
		switch(Precede(GetTopTR(operater),ch)){
    
			case '<':
				PushTR(operater,ch);
				cin>>ch;
				break;
			case '>':
				PopTR(operater,op);
				PopND(operand,b);
				PopND(operand,a);
				PushND(operand,Operate(a,op,b));
				break;
			case '=':
				PopTR(operater,op);
				cin>>ch;
				break; 	
		}			
	} 
	return GetTopND(operand); 
}

int main(){
    
	cout<<EvaluateExpression();
	return 0;
}

参考资料:
《数据结构 C语言版 第2版》严蔚敏 李冬梅 吴伟民

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Zhangguohao666/article/details/83620321

智能推荐

5G NR物理层之SRS学习小结_srs nr_星光125的博客-程序员秘密

SRS(Sounding Reference Signal,探测参考信号)1.SRS的作用?SRS虽然与上行数据或控制传输无关联,其主要作用是(1)用于信道质量估计,从而在上行链路中能进行频率选择性调度(比如对应上行多天线传输相关的不同参数)。(2)还可以有功率控制增强和当前未调度到的UE进行各种初始化功能。(3)假设上下行信道互益的情况下,利用信道对称性来估计下行的信道质量。2.SRS的资源说明(1)SRS的天线端口数由上层参数“nrofSRS-Ports“确定,数值可选范围为{1,2,4},SR

struts2上传文件(Common-FileUpload)_繁城落叶的博客-程序员秘密

1.准备工作。Struts2,默认使用的就是Common-FileUpload的文件上传框架,想要使用这个框架的话,需要将两个JAR文件导入到项目中,分别是:commons-io-2.4.jar和commons-fileupload-1.3.2.jar(将这两个包复制到WEB-INF\lib路径下)。导入完所需要的JAR包之后,就可以使用该框架进行文件的上传工作。

Markdown语法图文全面详解及其工具介绍_markdown 三角形_哇偶哇偶Z的博客-程序员秘密

转载自:https://www.jianshu.com/p/c0a2897ad4eb本文出自 AWeiLoveAndroid的博客【前言】写过博客或者github上面的文档的,应该知道Markdown语法的重要性,不知道的朋友们也别着急,一篇博客轻松搞定Markdown语法。话说这个语法超级简单,一看就会,不信你点开看看。目录:一、快捷键二、基本语法三、常用技巧四、高端用法五、Markdow工具六、不同平台功能对比七、使用MarkdowPad软件遇到的坑一、快捷键..

如何基于MYSQL做实时计算?_mysql为什么不能做实时统计_u011277123的博客-程序员秘密

云栖社区 2017-12-24 20:26:57有时候我们会有这样的场景,在某个接口中,数据已经很规范地存入到一张的MYSQL表中,现在想对这样的数据做一些实时或准实时处理,比如数据多模式存储、异步准实时业务流程、业务实时监控等。接口中处理流程如下:最原始的方法,是改动业务代码,将这些额外的处理流程作为同步流程,在更新MYSQL数据之后同步执行。如下图:但是这样的处理流

java8 集合对象求差集、交集_weixin_30293079的博客-程序员秘密

//交集List&lt;TFridCard&gt; list = cardLiStIn.stream().filter(item -&gt;msgModel.getPayload().stream().map(e -&gt; e.getTagname()).collect(Collectors.toList()).contains(item.getUniqueCode())).c...

数学(四)威尔逊区间_LightYoungLee的博客-程序员秘密

应用场景在点击率预估场景下,计算item的ctr并不能真实反映用户对这个item的喜爱程度,比如itemA的曝光次数为5,点击次数为2;itemB的曝光次数为100,点击次数为40,那么直观感觉itemB要比itemA更受欢迎,因为itemB的曝光次数多,但两个item的ctr是相同的(0.4),那么在这一维属性看来,这两个item在用户侧的喜好程度是相同的。这时需要引入威尔逊区间来解决上述问题。数学原理置信区间在上述应用场景中,用户的点击在理想情况下服从二项分布,二项分布的p值(上述ctr)的可信

随便推点

Lombok入门_lombok 构造函数_幻想具现的博客-程序员秘密

1.添加maven依赖<!-- lombok --><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version></dependency>2.在idea中添加lombok插件Settings–>Plugins–>搜索

时间序列预测方法_菜不卷的博客-程序员秘密

传统方法均值法用过去的某段时间内的均值作为预测值。季节性均值法均值法的一点优化,用过去的同类时间内的均值作为预测值。举个栗子:预测一下周五下午四点的销售量。均值法:所有天销售量的均值作为预测值;季节性均值法:我用过去n周周五下午四点的销售量的均值作为预测值。朴素法用最后的值作为预测值。季节性朴素法做最后的值的n个同类的值的均值(或者中位数等)作为预测值。再举个栗子:预测一下下周五下午四点的销售量。朴素法:我用周四(如果有)下午四点的值作为预测值。季节性朴素法,我用n个周周四下午四点的销售

不用锁表,没有异常:在高并发网络中高效的更新数据库数据的方式_weixin_33694172的博客-程序员秘密

很多Web系统的瓶颈在网络IO,所以很多系统都采用多Web服务器负载均衡,双DB做双机热备(其实就是只有一个DB,两台只有一台真正工作,死掉一台另一台顶上)的方式部署,在这个时候很多原本不是问题的系统也会产生很多的问题。这里我们假设有表Product,其定义如下:列明类型说明IdInt自增字段,实例的ID...

7.1 安装软件包的三种方法 7.2 rpm包介绍 7.3 rpm工具用法 7.4 yum工具用法 7.5 yum搭建本地仓库..._weixin_30609331的博客-程序员秘密

yum搭建本地仓库(视频中ppt小错误: gpcheck改为gpgcheck,yum cean 改为 yum clean)参数:-a:查询所有套件;-b&lt;完成阶段&gt;&lt;套件档&gt;+或-t &lt;完成阶段&gt;&lt;套件档&gt;+:设置包装套件的完成阶段,并指定套件档的文件名称;-c:只列出组态配置文件,本参数需配合"-l"参数使用;-d:只列出文本文件,本...

TCP/IP详解学习笔记--TCP连接的建立与终止_tcp故障66_Shreck66的博客-程序员秘密

1.基本概念由于TCP是一个面向连接的协议,无论在哪一方发送数据之前,都必须先在双方之间建立连接,接下来我们就讨论建立连接的具体过程2.建立TCP连接如下图所示: 1.首先请求端发送一个序列号为1(表明该方的起始序列号为1)的SYN段,此时由于连接还未建立成功,所以携带的数据为0,并前发送端还告诉接收端它所能接收的最大报文段mss 2.接收端收到SYN段后,也给对方回一个SYN端,告知对方它的其

剑指OFFER笔记_13_机器人的运动范围_JAVA实现_YesPlease的博客-程序员秘密

剑指OFFER笔记_13_机器人的运动范围_JAVA实现题目:机器人的运动范围解题思路代码函数主体部分代码测试部分代码运行结果截图LeetCode运行截图题目:机器人的运动范围地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。请问该机器人能够到达多少个格子?解题思路此题与前一题类似,采用回溯法。对(0,0)时的情况开始调用函数计算count,当此处的条件符合时,依次递归调用row±1和col

推荐文章

热门文章

相关标签