题解 P1175 【表达式的转换】
前置知识:求后缀表达式的值。 代码:
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1010;
ll sta[N],x;int top;
char s[N];
int main()
{
scanf("%s",s+1);
for(int i=1;s[i]!='@';i++)
{
if('0'<=s[i]&&s[i]<='9')
{
x=0;
while(s[i]!='.')x=x*10+s[i++]-'0';
sta[++top]=x;
}
else
{
x=sta[top--];ll &y=sta[top];
if(s[i]=='+')y+=x;
else if(s[i]=='-')y-=x;
else if(s[i]=='*')y*=x;
else if(s[i]=='/')y/=x;
}
}
printf("%lld\n",sta[1]);
return 0;
}
这题最麻烦的就是把中缀表达式转化成后缀表达式,难点是处理优先级的问题。 我们从左往右扫描中缀表达式,进行如下处理:
1.
建立一个符号栈ops和一个存后缀表达式的字符串p。
2.
如果是数字则加入p,因为形为
3.
如果是左括号,则加入ops。
4.
如果是右括号,则把符号栈中的运算符弹到p,直到遇到最近的左括号。最后,把一个左括号删除(不入p)。
5.
如果是运算符,则把优先级大于或等于的栈顶符号弹入p。因为这样能保证优先级高的先算。
为什么,优先级等于也要弹出呢?因为同级运算从左往右啊。
6.
重复2~~~5,直到扫描完毕。
7.
把剩下的符号依次弹入s。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#define ll long long//不超过2^31——等于2^31会爆int
using namespace std;
const int N=1e3+10;
//思路:把中缀表达式转成后缀表达式,再对后缀表达式进行处理。
//每处理一次运算,把数值栈中的数字输出,并把未处理的符号、数字输出。
char s[N];//中缀表达式
stack<char>ops;//符号栈
char p[N];int pl;//postfix Expression 后缀表达式
ll sta[N];int top;//数值栈
int grade(char op)//优先级
{
switch(op){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return 0;
}
void calc(char op)//计算
{
ll x=sta[top--],y=sta[top];
switch(op){
case '+':
y+=x;
break;
case '-':
y-=x;
break;
case '*':
y*=x;
break;
case '/':
y/=x;
break;
case '^':
y=pow(y,x);
}
sta[top]=y;
}
int main()
{
scanf("%s",s);int n=strlen(s);
for(int i=0;i<n;i++)
{
char c=s[i];
if('0'<=c&&c<='9')p[++pl]=c;//数字
else
{
//括号
if(c=='(')ops.push(c);
else if(c==')')
{
while(ops.size()&&(c=ops.top())!='(')
{
p[++pl]=c;
ops.pop();
}
ops.pop();
}
else//运算符
{
while(ops.size()&&grade(ops.top())>=grade(c))
{
p[++pl]=ops.top();
ops.pop();
}
ops.push(c);
}
}
}
while(ops.size())p[++pl]=ops.top(),ops.pop();
for(int i=1;i<=pl;i++)printf("%c ",p[i]);
puts("");//输出中缀表达式
for(int i=1;i<=pl;i++)//逐步处理后缀表达式
{
char c=p[i];
if('0'<=c&&c<='9')sta[++top]=c-'0';
else//运算符
{
calc(c);
for(int j=1;j<=top;j++)printf("%lld ",sta[j]);
for(int j=i+1;j<=pl;j++)printf("%c ",p[j]);
puts("");
}
}
return 0;
}