数据结构+机试题——栈的应用

本文深入探讨了一种用于计算数学表达式的算法实现,通过使用栈数据结构来处理运算符和数字,有效地解决了表达式的求值问题。文章详细介绍了算法流程,包括如何处理运算符的优先级和操作数的计算,提供了完整的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表达式的求值

 (第一遍忘了把运算结果压入数字栈 ๑乛◡乛๑)

#include<stack>
#include<stdio.h>
using namespace std;
char str[220];//保存表达式字符串
int mat[][5]={//优先级矩阵
//若mat[i][j]==1 则表示i号运算符优先级大于j号运算符
    //人为添加在表达式首尾的标记运算符为0号
	//+ - * /分别为1-4号
	1,0,0,0,0,
	1,0,0,0,0,
	1,0,0,0,0,
	1,1,1,0,0,
	1,1,1,0,0, 
}; 
stack<int> op;//运算符栈,保存运算符编号
stack<double> in;//数字栈,运算结果可能存在浮点数,所以保存元素为double
void getOp(bool &reto,int &retn,int &i){
//获得表达式中下一个元素 
//若函数运行结束时 引用变量reto为true 则表示该元素为一个运算符,其编号保存在引用变量retn中;
//否则,表示该元素为一个数字,其值保存在引用变量retn中。引用变量i表示遍历到的字符串下标 

if(i==0&&op.empty()==true){
	//若此时字符串遍历第一个字符,且运算符栈为空。我们人为添加编号为0的标记字符
	reto=true;//为字符串 
	retn=0;//编号为0 
	return;//返回 
}
if(str[i]==0)//若此时遍历字符为空字符,则表示字符已经被遍历完 
{
	reto=true;
	retn=0;
	return;
}
if(str[i]>='0'&&str[i]<='9')
{
	reto=false;//返回为数字 
}
else{
	reto=true;
	if(str[i]=='+'){
		retn=1;
	}
	else if(str[i]=='-'){
		retn=2;
	}
	else if(str[i]=='*'){
		retn=3;
	}
	else if(str[i]=='/'){
		retn=4;
	}
	i+=2;//i递增,跳过该运算字符和该运算字符后的空格 
	return;
}
retn=0;//返回结果为数字
for(;str[i]!=' '&&str[i]!=0;i++){
	//若字符串未被遍历完,且下一个字符不是空格,则依次遍历其后数字,计算当前连续数字字符表示的数值 
	retn*=10;
	retn+=str[i]-'0';
}
if(str[i]==' ')
i++;
return;

} 

int main(){
	while(gets(str)){
		if(str[0]=='0'&&str[1]==0) break;//若输入只有一个0,则退出
		bool retop; int retnum;
		int idx=0;//遍历到的字符串下标
		while(!op.empty()) op.pop();
		while(!op.empty()) in.pop();//清空两个栈
		while(true){
			getOp(retop,retnum,idx);//获取表达式中下一个元素 
			if(retop==false){
				//若该元素为数字 
				in.push((double)retnum);
			}
			else{
				double tmp;
				if(op.empty()==true||mat[retnum][op.top()]==1){
					op.push(retnum);
			//若运算符栈为空或者当前遍历到的运算符优先级大于栈顶运算符 
			//将该运算符压入运算符堆栈 
				}
				else{
					while(mat[retnum][op.top()]==0){
			//当前运算符优先级小于栈顶运算符则重复循环
			    	int ret=op.top();//保存栈顶运算符
					op.pop();//弹出 
					double b=in.top();
					in.pop();
					double a=in.top();
					in.pop(); 
					//从数字堆栈栈顶弹出两个数字,依次保存在遍历a,b中
					if(ret==1) tmp=a+b;
					else if(ret==2) tmp=a-b;
					else if(ret==3) tmp=a*b;
					else tmp=a/b; 
					in.push(tmp);
					}
					op.push(retnum);//将当前运算符压入运算符栈 
				} 
			
			}
			if(op.size()==2&&op.top()==0) break;
			//若运算符栈只有两个元素 且栈顶元素为标记运算符,则表示表达式求值结束
			 
		} 
		printf("%.2f\n",in.top());	
	}
	return 0;
}

 结果示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值