XDOJ 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
-
输出样例
1503
-
解题思路
这道题和上一道后缀表达式求值问题有很大不同,上一道题数值为0~9,这次操作数范围为正整数,所以压栈的时候就不能按字符一个一个来压栈,先要判断它的位数计算出这个数得真正数值之后再进行压栈。//我刚开始做的时候没注意,导致36变成了3和6.。用字符串处理数字问题的时候一定要注意看他是否为多位数啊!!!
还有不同元素之间用空格隔开也和上一题不同,但正是这个小细节方便了这道题的做法。
这道题得大体做法是从右到左倒过来处理字符串,采用栈作为辅助存储结构,碰到操作数则入栈,碰到操作符则连续两次出栈,然后进行计算,所得结果入栈,直至整个字符串处理完毕。
因为要倒过来处理字符串,而对数字的处理倒过来不好计算。所以我选择先正序遍历一遍将数字处理好存到另一个数组中。当要进行压栈弹栈以及计算操作时,逆序遍历的时候碰到数字就把数组中的数字拿出来直接进行压栈,在用一个while循环跳过后面多余的数字。例:
//比如说
+ * + 42 8 – 36 6 / 9 3
先正向求数字存到num数组中 结果:num={42,8,36,6,9,3}
逆序遍历时碰到3 判断为数字 取出num中的3压栈
碰到9 判断为数字 取出num中的9压栈
碰到6 判断为数字 取出num中的6压栈
碰到36 判断6为数字,取出num中的36压栈,然后跳过后面的3再进行判断。
- 完整代码
#include<stdio.h>
#include<string.h>
int main()
{
char str[100];
int i,top,stack[100],len,num[100];
int k=0;
top=-1;//栈为空
gets(str);
len=strlen(str);
for(i=0;i<len;i++)
{
if(str[i]>='0'&&str[i]<='9')//操作数
{
int count=0;
while(str[i]!=' '&&str[i]!=0)
{
count=count*10+str[i]-'0';//计算出正确的数字
i++;
}
num[k++]=count;//数字数组
}
}
for(i=len-1;i>=0;i--)
{
if(str[i]>='0'&&str[i]<='9')//碰到操作数
{
top++;
stack[top]=num[--k];//将num中的数字压栈
while(str[i]!=' ')//利用空格跳过后面的多余数字
i--;
}
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
{
int t1,t2;
t1=stack[top--];//第一个出栈的数
t2=stack[top--];//第二个出栈的数
if(str[i]=='+')
stack[++top]=t1+t2;//将计算结果压栈
if(str[i]=='-')
stack[++top]=t1-t2;
if(str[i]=='*')
stack[++top]=t1*t2;
if(str[i]=='/')
stack[++top]=t1/t2;
}
}
printf("%d",stack[top]);
return 0;
}