XDOJ 308 前缀表达式求值

XDOJ 308 前缀表达式求值 如果对您有帮助,请给代码人点个赞哦,刚刚又掉了几根头发😱😱😱&#x1f631

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
#include
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;
}