标题
#include <iostream>
#include<bits/stdc++.h>
#include <stack>
using namespace std;
/*
4 + 2 + 4/2
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
*/
int cmp(const char c1,const char c2) //判断优先级
{
if(c1==c2) //相同操作符,及同级操作符
return 0;
if((c1=='*'||c1=='/')&&(c2=='*'||c2=='/'))//同级
return 0;
if((c1=='*'||c1=='/')&&(c2=='+'||c2=='-'))//
return 1;
if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'))
return -1;
}
double compute(const char* pstr) //计算结果
{
stack<double> copnd; //存储操作数
stack<char> copter; //存储操作符:+,-,*,/
char cnum[512]; //存储提取的操作数
int i=0;
int len=strlen(pstr);
double t1=0,t2=0,t3=0;//t1,t2:存储先后出栈的两操作数; t3:存储计算结果
for(i=0;i<len;++i)
{
if(pstr[i]>='0'&&pstr[i]<='9') //提取操作数,注意操作数超过10时如何处理
{
int k=0;double tn=0;
while(isdigit(pstr[i]))
cnum[k++]=pstr[i++];
cnum[k]='\0';
tn=atoi(cnum);
memset(cnum,0,sizeof(cnum));
copnd.push(tn);
cout<<"opnd: push("<<tn<<")"<<endl;
i=i-1; //提取一个操作数完后,i已经指向下一位,需要重新调整,画图可以更好理解
}
else if(pstr[i]=='+'||pstr[i]=='-'||pstr[i]=='*'||pstr[i]=='/')
{
if(copter.empty()) //若栈为空,则直接将操作符入栈
{
copter.push(pstr[i]);//
cout<<"opter: push("<<pstr[i]<<")"<<endl;
}
else
{
switch(cmp(copter.top(),pstr[i]))
{
case 0: case 1: //同优先级操作符操作:先将操作数栈最顶层的两个元素出栈并根据操作符计算结果,然后将结果入操作数栈
t1=copnd.top();
cout<<"opnd: pop("<<t1<<")"<<endl;
copnd.pop();
t2=copnd.top();
copnd.pop();
cout<<"opnd: pop("<<t2<<")"<<endl;
switch(copter.top())
{
case '+':
t3=t2+t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '-':
t3=t2-t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '*':
t3=t2*t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '/':
if(t1==0) //零除情况要考虑
return -1;//zero-divide
t3=(double)(t2/t1);
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
default:break;
}
copter.pop(); //同级操作符出栈
copter.push(pstr[i]); //同级操作符入栈
break;
case -1:
copter.push(pstr[i]); //栈内操作符优先级小于所提取的操作符,则直接将提取的操作符入栈
break;
default:break;
}
}
}
}
while(!copter.empty()) //当上述循环遍历至结尾时,至少最后的2个操作数未进行计算(至多3个操作数),可以画栈图理解
{
t1=copnd.top();
copnd.pop();
t2=copnd.top();
copnd.pop();
switch(copter.top())
{
case '+':
t3=t2+t1;
copnd.push(t3);
break;
case '-':
t3=t2-t1;
copnd.push(t3);
break;
case '*':
t3=t2*t1;
copnd.push(t3);
break;
case '/':
if(t1==0)
return -1;//zero-divide
t3=(double)(t2/t1);
copnd.push(t3);
break;
default:break;
}
copter.pop();
}
return t3;
}
int main()
{
char s[10040];
gets(s);
cout<<compute(s)<<endl;
return 0;
}