第五周PTA笔记 后缀表达式+后缀表达式计算
后缀表达式
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右进行(不用考虑运算符的优先级)。
如:中缀表达式 3(5–2)+7 对应的后缀表达式为:352-7+ 。
请将给出的中缀表达式转化为后缀表达式并输出。
输入格式:
输入仅一行为中缀表达式,式中所有数字均为个位数,表达式长度小于1000。
输出格式:
输出一行,为后缀表达式,式中无空格。
输入样例:
2+4*8+(8*8+1)/3
输出样例:
248*+88*1+3/+
发现一个宝藏博文中缀表达式转后缀表达式(非常简单易懂),通过一个同学的博客也发现了这个挺好的视频中缀表达式转后缀表达式(逆波兰表达式)冯强
思路其实大家都懂,就是写起来这错那错。我的代码比较复杂,但是总的逻辑是我自己比较明白的。就是交代一下需要注意的几个点,一开始测了很多数据在在自己电脑上运行都是对的,但交上去就全错,很崩溃啊,因为这个搞了好久。1.后来又想了一些可能的数据,例如1+2+3+4+5,像这样运算符连续相等的,这就让在if的判断多了一个条件。2.连续的括号到最后输出会多出来括号,例如((1+2)-(2-3))/6,在中间的判断运行部分没有改,因为数字和运算符的相对顺序是没有错的,于是就在最后输出的地方多了if判断。3.例如:12345+2-4*6/3,当一个比较低级的运算符后面有连续比较高级的运算符,就是➖后有连续的✖或➗,这个地方改得有点久,就是把if条件合并的地方拆开判断。
代码如下繁琐得很,就将就看吧哈哈哈
#include<stdio.h>
#include<string.h>
char s[1005],c[1005],a[1005];//数组a是储存操作符,数组c是储存最终答案
int judge(char x);//判断运算符的优先级
int main()
{
scanf("%s",s);
int i,r=0,t=0,n;
for(i=0;s[i]!='\0';i++)
{
if(s[i]>47&&s[i]<58){
c[r]=s[i];
r++;
}
else{
if(s[i]=='('){
a[t]=s[i];
t++;
i++;
while(s[i]!=')'){
if(s[i]>47&&s[i]<58){
c[r]=s[i];
r++;
i++;
}
else{
if(judge(a[t-1])>judge(s[i])&&a[t-1]!='('){
t--;
while(a[t]!='('){
c[r]=a[t];
r++;
t--;
}
t++;
a[t]=s[i];
t++;
i++;
}
else if(judge(a[t-1])==judge(s[i])&&a[t-1]!='('){//这一步就是上述提到的第三点
c[r]=a[t-1];
a[t-1]=s[i];
r++;
i++;
}
else{
a[t]=s[i];
t++;
i++;
}
}
}
t--;
while(a[t]!='('){
c[r]=a[t];
r++;
t--;
}
}//遇到()的情况
else{
if(judge(s[i])<judge(a[t-1])&&t>0){
t--;
while(t>=0){
c[r]=a[t];
r++;
t--;
}
t++;
a[t]=s[i];
t++;
}
else if(judge(s[i])==judge(a[t-1])&&t>0){//这一步就是上述提到的第三点
c[r]=a[t-1];
a[t-1]=s[i];
r++;
}
else{
a[t]=s[i];
t++;
}
}
}
}
t--;
while(t>=0){
c[r]=a[t];
t--;
r++;
}
n=strlen(s);
for(i=0;i<n;i++)
{
if(c[i]!='('&&c[i]!=')')printf("%c",c[i]);
}
return 0;
}
int judge(char x)
{
if(x=='+'||x=='-')return 1;
else if(x=='*'||x=='/')return 2;
else if(x=='^')return 3;
return 4;
}
后缀表达式计算
Kunkun学长觉得应该让学弟学妹了解一下这个知识点:后缀表达式相对于中缀表达式更容易让计算机理解和学习。现在kunkun学长给出一串后缀表达式,你能帮他算出这个后缀表达式的值吗?
输入格式:
第一行输入后缀表达式长度n(1<=n<=25000);
第二行输入一个字符串表示后缀表达式(每个数据或者符号之间用逗号隔开,保证输入的后缀表达式合法,每个数包括中间结果保证不超过long long长整型范围)
输出格式:
输出一个整数,即后缀表达式的值。
输入样例1:
6
10,2,+
输出样例1:
12
输入样例2:
14
2,10,2,+,6,/,-
输出样例2:
0
本题参考了后缀表达式C语言实现。
思路:用数组来做的,对于自己来说比较好理解。这题感觉比上一题让我容易理解,所以先写了这题,这个运算规则就是遇到运算符就将运算符的前两个数字进行运算。而用字符表示的数字不好计算,于是我将数字存在一个long long int的数组当中,并在计算过程中将计算得出的值存入这个数组的同时不断更新这个数组。
要注意以下几点:1.计算中可能会遇到负数,而数字前的"-"要和减号区别清楚,这要新列出一个情况。
2.我一开始设置的是long long int的整型,由于粗心在输入时写的是%d,在在自己的电脑上运行没错,到PTA上就段错误了,改过来之后就AC了。最后的输出也记得要写%lld,试验了一下,写%d会部分错误,写%ld也可以AC。
3.遇到➗和➖要分清楚哪个数字在前,也就是被除数或者被减数。
代码如下:
#include<stdio.h>
char s[25005];
long long int a[25005];
int main()
{
long long int n,i,t=0,r=0;
scanf("%lld %s",&n,s);
for(i=0;i<n;i++)
{
if(s[i]>47&&s[i]<58){
while(s[i]!=','){
a[r]=a[r]*10+(s[i]-'0');
i++;
}
r++;
}
else if(s[i]=='-'&&s[i+1]>47&&s[i+1]<58){
i++;
while(s[i]!=','){
a[r]=a[r]*10+(s[i]-'0');
i++;
}
a[r]=-a[r];
r++;
}
else if(s[i]=='+'){
a[r-2]=a[r-2]+a[r-1];
a[r-1]=0;
r--;
}
else if(s[i]=='-'){
a[r-2]=a[r-2]-a[r-1];
a[r-1]=0;
r--;
}
else if(s[i]=='/'){
a[r-2]=a[r-2]/a[r-1];
a[r-1]=0;
r--;
}
else if(s[i]=='*'){
a[r-2]=a[r-2]*a[r-1];
a[r-1]=0;
r--;
}
}
printf("%d",a[0]);
return 0;
}