计算

题目描述

 

小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”求出的值就是密码。小明数学学得不好,还需你帮他的忙。(“/”用整数除法,取商)

输入

输入共1行,为一个算式。

输出

 输出共1行,就是密码。

样例输入

1+(3+2)*(7^2+6*9)/(2)

样例输出

258

提示

 100%的数据满足:算式长度<=30 其中所有数据在231-1的范围内。

解题思路:

此题的关键是将运算符与数分开存入两个栈中。每次将符号压入栈前判断该运算符的优先级是否大于前一个运算符。若前一个运算符大则前一个运算符与刚存入的两个数进行运算然后再压入栈中。最终完成运算。

 

 

 

以下代码借鉴过大神的思路,我加入了详细的备注。

借鉴于这位大神

https://blog.csdn.net/u011123263/article/details/14457865

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int rate(char a)//该函数给每个运算符定优先级 
{
	if(a=='+'||a=='-')return 1;
	if(a=='*'||a=='/')return 2;
	if(a=='^')return 3;
	if(a=='(')return 0;
}
void cal(stack<int>&a,stack<char>&b)//该函数进行计算,每次出栈两个数和一个运算符进行计算,结果再压入存数栈中 
{  int num1=0,num2=0;
 char s;
	num1=a.top();
	a.pop();
	 num2=a.top();
	 a.pop();
	 s=b.top();
	 b.pop();
	if(s=='+')a.push(num2+num1);
else	if(s=='-')a.push(num2-num1);
else	if(s=='*')a.push(num2*num1);
else	if(s=='/')a.push(num2/num1);
else	if(s=='^')
	{  int res=1;
		for(int i=1;i<=num1;i++)
		 res=res*num2;
		 a.push(res);
	}
}
int main()
{
	char s[1000];
	cin>>s;
	int flag=0,sum=0;
	stack<int>calnum;
	stack<char>calsign;
	for(int i=0;i<strlen(s);i++)
	{  
		if(isdigit(s[i]))
		 {
		 	sum=sum*10+s[i]-'0';//sum用于存储数字 
		 	flag=1;
		 }
		   else
		   {
		   	 if(flag){ calnum.push(sum);flag=0;sum=0;}//flag用于标记字符串的数是否读完,以遇到符号结束 后清零 
		   	 if(s[i]=='(')
		   	 {
		   	 	calsign.push(s[i]);//遇到左括号直接压入符号栈后结束 
		   	 	 continue;
				}
				if(s[i]==')')
				{
					while(calsign.top()!='(')
					 {
					 	cal(calnum,calsign); //配对的括号内优先进行计算,直到遇到左括号为止,然后将左括号出栈 
					 }
					 calsign.pop();
					 continue;
				}
				if(calsign.empty())calsign.push(s[i]);//若符号栈为空,直接压入符号 
				else
				{
					while(!calsign.empty()&&rate(calsign.top())>=rate(s[i]))//若要压入符号优先级比栈顶的优先级要小,则计算 
					  cal(calnum,calsign);
					  calsign.push(s[i]);
				}
		   }
	}
	if(flag){
		calnum.push(sum);//因为最后不以符号结尾所以最后一个数需再做处理 
	}
	 while(!calsign.empty())cal(calnum,calsign);
	 cout<<calnum.top()<<endl;
	 return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值