以 (3+5)*100+22*2+34/2 为例
1、当遇到数字时,入数字栈。
2、当遇到左括号(或者是符号优先级比栈顶优先级高的时候,入符号栈。
3、当栈顶为(,当前符号为),出符号栈。
4、若当前符号优先级小于栈顶优先级,则连续出两个数字,一个运算符,进行运算后,压入数字栈。
最好一开始在符号栈内压入一个'\0',当栈顶为'\0'且当前符号也为'\0',运算结束。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
using namespace std;
const int maxn=10000+10;
char ch[maxn];
stack<char>oc;
stack<double>on;
double toNum(char c,int &k)
{
double s=0.0,p=0.0;
bool flag=0;
while(ch[k]>='0'&&ch[k]<='9'||ch[k]=='.')
{
if(ch[k]>='0'&&ch[k]<='9')
{
if(!flag)
{
s=s*10+ch[k]-'0';
}
else
{
s=s+p*(ch[k]-'0');
p*=0.1;
}
}
else
{
flag=1;
}
k++;
}
return s;
}
int priority(char c)
{
switch (c)
{
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
case '(':
return 0;
case ')':
return 0;
default:
return -1;
}
}
double cal(char c,double x,double y)
{
switch (c)
{
case '*':
return x*y;
case '/':
return x/y;
case '+':
return x+y;
case '-':
return x-y;
}
}
int main()
{
while(scanf("%s",ch))
{
while(oc.size())
oc.pop();
while(on.size())
on.pop();
oc.push('\0');
int cnt=0;
char tmp=ch[cnt];
int len=strlen(ch);
ch[len]='\0';
while(true)
{
//cout<<tmp<<endl;
if(tmp=='\0'&&oc.top()=='\0')
break;//结束
else if(tmp>='0'&&tmp<='9'||tmp=='.')
{
on.push(toNum(tmp,cnt));
}
else if(tmp==')'&&oc.top()=='(')
{
oc.pop();
cnt++;
}
else if(tmp=='('||priority(tmp)>priority(oc.top()))
{
oc.push(tmp);
cnt++;
}
else if(priority(tmp)<=priority(oc.top()))
{
double x=on.top();
on.pop();
double y=on.top();
on.pop();
tmp=oc.top();
oc.pop();
double s=cal(tmp,y,x);
on.push(s);
}
tmp=ch[cnt];
}
printf("%.3f\n",on.top());
}
}
//((4+3)*2)