以 (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)