表达式求值(第二种方法)
在初学表达式求值时便写了一篇博客表达式求值
但是后来发现这种方法不仅操作起来困难而且不容易记忆
现在用课本上的知识重写了一遍表达式求值,发现更容易操作,这里以南洋理工一道表达式求值习题为例链接,为了追求一般化,我特地将特殊性的字符写成了函数,便于转移到其他习题求解。
这里思路是这样的,
我们用两个栈
依次读入表达式中的每个字符,若是操作数则进第一个栈,若是运算符则进第二个栈,运算符进栈时需要与栈顶元素循环比较,若是优先级较低,那么需要将栈顶运算符弹出并将两个操作数弹出做相应运算并入操作数的栈,直至最后出结果。
详见代码
#include <bits/stdc++.h>
using namespace std;
int isok(char s)
{
if(s=='*'||s=='/')
return 3;
else if(s=='+'||s=='-')
return 2;
else if(s=='!')
return 1;
return 0;
}
stack<char>st1;
stack<int>st2;
string str;
int k;
void cacu(char s)
{
if(s=='+')
{
int a=st2.top();
st2.pop();
int b=st2.top();
st2.pop();
st2.push(a+b);
}
else if(s=='-')
{
int a=st2.top();
st2.pop();
int b=st2.top();
st2.pop();
st2.push(b-a);
}
else if(s=='*')
{
int a=st2.top();
st2.pop();
int b=st2.top();
st2.pop();
st2.push(b*a);
}
else if(s=='/')
{
int a=st2.top();
st2.pop();
int b=st2.top();
st2.pop();
st2.push(b/a);
}
else if(s=='!')
{
int a=st2.top();
st2.pop();
int sum1=0,sum2=0;
while(a)
{
sum1+=a%10;
a/=10;
}
int b=st2.top();
st2.pop();
while(b)
{
sum2+=b%10;
b/=10;
}
st2.push(max(sum1,sum2));
}
}
char fi(char s)
{
char a;
if(s=='S')
{
a='!';
}
return a;
}
bool iso(char s)
{
if(s=='S')
return 1;
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
while(!st1.empty())
st1.pop();
while(!st2.empty())
st2.pop();
cin>>str;
int p=0;
stack<char>st;
for(int i=0;i<str.size();i++)
{
if(str[i]==',')
{
char s=st.top();
st.pop();
str[i]=fi(s);
}
else if(iso(str[i]))
st.push(str[i]);
}
//cout<<str<<endl;
for(int i=0;i<str.size();i++)
{
if(isalpha(str[i]))
continue;
if(str[i]=='(')
{
st1.push(str[i]);
}
else if(str[i]==')')
{
while(st1.top()!='(')
{
char s=st1.top();
st1.pop();
cacu(s);
}
st1.pop();
}
else
{
int p=isok(str[i]);
if(p==0)
{
int sum=0,j;
for(j=i;j<str.size();j++)
{
if(str[j]>='0'&&str[j]<='9')
{
sum*=10;
sum+=(int )str[j]-'0';
}
else
break;
}
i=j-1;
st2.push(sum);
}
else
{
while(!st1.empty()&&isok(st1.top())>p)
{
char s=st1.top();
st1.pop();
cacu(s);
}
st1.push(str[i]);
}
}
}
while(!st1.empty())
{
char s=st1.top();
st1.pop();
cacu(s);
}
cout<<st2.top()<<endl;
st2.pop();
}
return 0;
}