308 前缀表达式求值
前缀表达式求值
问题描述:
对前缀表达式求值,其中操作数为正整数,运算符只包含+-*/,运算结果也为整数。如(42+8)*(36-6)+9/3的前缀表达式为:+ * + 42 8 – 36 6 / 9 3。
输入说明:
输入为一行,一个字符串表示的前缀表达式,如:+ * + 42 8 – 36 6 / 9 3,表达式的长度不超过100,式中不同元素之间用空格隔开。
输出说明:
输出表达式的值(这里只考虑计算结果为整数的情况)。
输入样例:
+ * + 42 8 – 36 6 / 9 3(word文档里的 ‘-’有问题,害的我死循环!!!!!运行不能直接复制,手输就对了)
输出样例:
1503
提示
从右到左倒过来处理字符串,采用栈作为辅助存储结构,碰到操作数则入栈,碰到操作符则连续两次出栈,然后进行计算,所得结果入栈,直至整个字符串处理完毕。
思路:
1、核心算法如提示所示,用栈。
2、比较难搞的是这里面存在char转int的问题,尤其是还有两位数。
考虑到要逆序遍历,用pow函数实现(第24行表达式,先乖乖手推的),用weight表示每位数的权重
3、逆序遍历str的时候
分类讨论str[i]:一共三种情况,为空格/为运算符/为运算数(三个if)
用whille循环:好处是一口气写完,坏处就是......小粥逻辑不清(见attention)
代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<math.h> 5 int main() 6 { 7 char str[100]; 8 9 int stack[100]; 10 int top=-1; 11 int i,j; 12 13 gets(str); 14 int length=strlen(str); 15 16 i=length-1; 17 while(i>=0) 18 { 19 if(str[i]>='0'&&str[i]<='9') 20 { 21 int data=0;int weight=0; 22 while(str[i]!=' ') 23 { 24 data+=(str[i]-'0')*pow(10,weight); 25 i--; 26 weight++; 27 } 28 stack[++top]=data; 29 } 30 if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/') 31 { 32 int top1,top2; 33 top1=stack[top--]; 34 top2=stack[top--]; 35 if(str[i]=='+') 36 { 37 stack[++top]=top1+top2; 38 } 39 if(str[i]=='-') 40 { 41 stack[++top]=top1-top2; 42 } 43 if(str[i]=='*') 44 { 45 stack[++top]=top1*top2; 46 } 47 if(str[i]=='/') 48 { 49 stack[++top]=top1/top2; 50 } 51 i--; 52 } 53 if(str[i]==' ') i--; 54 } 55 printf("%d",stack[top]); 56 return 0; 57 58 }
Attention:
1、幂函数很久没用了(pow不是power)
语法复习:double pow (double x, double y),其中x为底数,y为指数。 例如,要计算2的3次方,可以使用pow (2, 3)来实现。
2、gets也很久没用了(区别于getchar)
*第一遍用了,然后报错:[Error] too many arguments to function 'int getchar()'
区别:gets获取串,getchar获取单个字符
3、用了while不好的就是会忘掉i--,以及i--写的位置不对(第25/51/53行,尤其是后两个i--不能出if大括号)
其实还是思路不清,debug的时候改过来了
需要复习:前中后缀表达式(咬牙切齿.jpg
想思路的时候参考了:XDOJ 308 前缀表达式求值_前缀表达式求值,其中操作数为正整数,运算符只包含+-*/,运算结果也为整数。-CSDN博客
也是很好的思路呢!