栈实现表达式求值

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef  char elemtype;
typedef struct node{
	elemtype data;
	struct node* next;
}LinkStack;
typedef struct node1{
	int data;
	struct node1* next;
}LinkStack1;
bool push(LinkStack **top, elemtype e);
bool pop(LinkStack  **top, elemtype  &e);
bool pushi(LinkStack1 **top, int e);
bool popi(LinkStack1  **top, int  &e);
int cmpoptr(char a,char b);
int op(int a,int b,char optr);
int main(){
	//给定含+-*/(),数字的字符串,用#表示结束,用O(n)算出表达式结果
	char str[1001]={'\0'},abandon;
	LinkStack *optrtop=NULL;
	LinkStack1 *opndtop=NULL;
	push(&optrtop,'#');
	scanf("%1000s",str);
	for(int i=0;str[i];i++){
		int num=0,flag=0,a,b,result;//strcmp('0',str[i])<=0&&strcmp(str[i],'9')<=0 
		for(;'0'<=str[i]&&str[i]<='9';i++,flag=1){
			num*=10;
			num+=(str[i]-'0');
		}
		if(flag){
			i--;
			pushi(&opndtop,num);
		}	
		else{
			if(cmpoptr(optrtop->data,str[i])<0){
				push(&optrtop,str[i]);
			}
			else if(cmpoptr(optrtop->data,str[i])==0)pop(&optrtop,abandon);
			else{
				char optr;
				popi(&opndtop,b);
				popi(&opndtop,a);
				pop(&optrtop,optr);
				result=op(a,b,optr);
				pushi(&opndtop,result);
				i--;
			} 
		}
	}
	int final;
	popi(&opndtop,final);
	printf("the result is %d",final); 
	return 0;
} 
int cmpoptr(char a,char b){
	//默认ab只可能为+-*/()#
	if(a=='+'||a=='-'){
		if(b=='*'||b=='/'||b=='(')return -1; 
		else return 1;
	}
	else if(a=='*'||a=='/'){
		if(b=='(')return -1;
		else return 1;
	}
	else if(a=='('){
		if(b==')')return 0;
		else return -1;
	}
	else if(a==')')return 1;
	else return -1;//a=='#'
}
int op(int a,int b,char optr){
	if(optr=='+')return a+b;
	else if(optr=='-')return a-b;
	else if(optr=='*')return a*b;
	else if(optr=='/')return a/b;//就整数除法吧,偷懒不管了 
	else exit(1);//其余情况不受理 
}

bool push(LinkStack **top, elemtype e){
	LinkStack *tem=(LinkStack*)malloc(sizeof(LinkStack));
	if(!tem)exit(1);
	tem->data=e;
	tem->next=*top;
	*top=tem;
	return 1;
}
bool pop(LinkStack  **top, elemtype  &e){
	if(!*top)exit(1);
	LinkStack *tem=(*top)->next; 
	e=(*top)->data;
	free(*top);
	*top=tem;
	return 1;
}
bool pushi(LinkStack1 **top, int e){
	LinkStack1 *tem=(LinkStack1*)malloc(sizeof(LinkStack1));
	if(!tem)exit(1);
	tem->data=e;
	tem->next=*top;
	*top=tem;
	return 1;
}
bool popi(LinkStack1  **top, int &e){
	if(!*top)exit(1);
	LinkStack1 *tem=(*top)->next; 
	e=(*top)->data;
	free(*top);
	*top=tem;
	return 1;
}

代码思路

核心算法

使用双栈法(运算符栈 + 操作数栈)实现中缀表达式求值,基于运算符优先级进行比较和计算。

执行流程

  1. 初始化:运算符栈压入'#'作为结束标志

  2. 扫描表达式

    • 遇到数字:解析完整数字后压入操作数栈

    • 遇到运算符:

      • 优先级高于栈顶:压入运算符栈

      • 优先级等于栈顶(括号匹配):弹出左括号

      • 优先级低于栈顶:弹出运算符和两个操作数进行计算,结果压回操作数栈

代码用法

输入格式

text

复制代码
表达式#

示例:2*(3+4)/5#

输出

直接输出表达式计算结果

功能特点

  1. 支持的运算符+, -, *, /, (, )

  2. 数字处理:多位数自动解析

  3. 优先级规则

    • *, / > +, -

    • 括号改变优先级

  4. 错误处理:内存分配失败时直接退出

代码限制

  1. 整数除法:使用C++整数除法,会截断小数部分

  2. 错误处理简单:遇到非法表达式直接崩溃,无友好提示

  3. 输入长度限制:最多1000个字符

  4. 运算符限制:不支持求模、幂运算等其他运算符

  5. 负数处理 :不支持负号作为一元运算符(如-5

  6. 空格处理:输入中不能包含空格

  7. 结束标志 :必须用#结束表达式

潜在改进方向

  • 添加表达式合法性检查

  • 支持浮点数运算

  • 增加错误信息提示

  • 支持更多运算符和函数

  • 处理一元负号

  • 移除必须的#结束符

相关推荐
wuweijianlove38 分钟前
算法性能的渐近与非渐近行为对比的技术4
算法
_dindong1 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
AI成长日志1 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
黎阳之光1 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
skywalker_111 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
wfbcg2 小时前
每日算法练习:LeetCode 209. 长度最小的子数组 ✅
算法·leetcode·职场和发展
_日拱一卒2 小时前
LeetCode:除了自身以外数组的乘积
数据结构·算法·leetcode
计算机安禾2 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
SatVision炼金士2 小时前
合成孔径雷达干涉测量(InSAR)沉降监测算法体系
算法