后缀表达式求值

来源:互联网 发布:大数据龙头股票 编辑:程序博客网 时间:2024/05/19 03:45

**

问题 H: 后缀表达式求值

**

  • 时间限制: 1 Sec 内存限制: 128 MB
  • 提交: 1116 解决: 500

  • 题目描述

为了便于处理表达式,常常将普通表达式(称为中缀表示)转换为后缀{运算符在后,如X/Y写为XY/表达式。在这样的表示中可以不用括号即可确定求值的顺序,如:(P+Q)(R-S) → PQ+RS-。后缀表达式的处理过程如下:扫描后缀表达式,凡遇操作数则将之压进堆栈,遇运算符则从堆栈中弹出两个操作数进行该运算,将运算结果压栈,然后继续扫描,直到后缀表达式被扫描完毕为止,此时栈底元素即为该后缀表达式的值。

  • 输入

输入一行表示后缀表达式,数与数之间一定有空格隔开(可能不只一个空格),最后输入@表示输入结束。

数据保证每一步的计算结果均为不超过100000的整数。

  • 输出

输出一个整数,表示该表达式的值.

  • 样例输入

14 3 20 5 / *8 - + @


  • 样例输出

18

知识背景:


    • 百度表达式的种类,知道中序表达式,后序表达式的意思

    • 中序表达式:中序表达式 就是操作运算符在中间,被操作数在操作运算符的两侧(一前一后)的表达式.我们平时书面上的表达式大多数都是中序表达式.

    • 后序(后缀)表达式:要求每一个操作符出现在其操作数之后.例如:中序A/B*C的后序表达式为AB/C*,其中除号紧接其操作数A和B之后.依次类推. 写表达式的后序表达式一般是为了便利于计算机编程中栈的实现,所以用的较多.
  • -

分析题意

  • 这个题目的要求就是先按照从头到尾的顺序扫,将题目中的操作数先存起来(b
  • 接着若遇到了操作符,则弹出顶上的前两个数字,假设最上面的数字从顶到末依次为a,b那么进行运算,b 该操作符号 a,此处要注意的就是出栈顺序和实际运算数的顺序相反,所以是b操作符a
  • 接着遍历字符串,是数字就先存起来,是操作符就弹出俩数字进行运算
  • 当输入的字符串到了结尾符号(该题目中是@),那么意味着字符串遍历完毕,栈顶元素就是结果了,输出栈顶元素即可

    需要实现的功能有

    1. 判断该字符是否为运算符

    2. 压数字入数字栈

    3. 跳过空格

    4. 遇到运算符从栈定弹出俩数进行运算

    5. char类型数字子串转换为int类型

代码片段

栈的使用函数在这里就不赘述了,该题目属于全篇只是使用栈不需要将底层的一些函数变形

int IsOperator(char ch)//判断ch是否为操作符 {     switch (ch)     {     case '+':return 1; break;     case '-':return 1; break;     case '*':return 1; break;     case '/':return 1; break;     case ' ':return 1; break;     case '@':return 1; break;     }     return false; } 
//该函数实现的功能有,未发现有运算符时,压数字入数字站,跳过空格,存在运算符时提出俩数运算 int PostInStack(const char *string, pStack operand)//返回计算结果 {     int i=0;// i as xiabiao     while(string[i]!='@')     {         /*实现多位数的计算存储和识别运算符与非运算符技术*/        if(!IsOperator(string[i])) //若不是运算符,那么将char串数字转化为int的一个数        {                 int sum=string[i]-'0';                 ++i;// pointer move ahead                  while(!IsOperator(string[i]))                 {                 sum=sum*10+string[i]-'0';                 ++i;                 }                 push(operand,sum); //转化完毕就压入数字栈                while(string[i]==' ') //跳过题中随机的空格                {                     ++i;                 }//  remove space                 /**********************************/        }             else//是操作符号就进行运算            {                int a,b,res;                pop(operand,&a);                pop(operand,&b);                switch(string[i])                //本来这里想封装一下switch做个函数,无奈gcc编译错误,原因我也不懂               {                      case'+':res=a+b;break;                      case'/':res=b/a;break;                      case'-':res=b-a;break;                      case'*':res=a*b;break;                }                push(operand,res); //运算完毕后存入栈顶               i++;                while(string[i]==' ')                {                    ++i;                }             }     }     int result=GetTop(operand,&result); //扫完后结果在栈顶    return result; } 
int Input(char **string) //因为OJ上静态变量内存分配无法满足题意, 只得手动分配{     *string = (char *)malloc(sizeof(char)* 1000);     gets(*string);     return true; } int main(void) {     Stack Operand, Operator;     int result;     initial(&Operand);//初始化操作数栈     char *string;     Input(&string);     /*printf("%s\n", string);     system("pause");*/    result = PostInStack(string, &Operand);//后序遍历直接入栈     printf("%d\n", result);     //system("pause");     return 0; } 

栈的基本操作函数在此不赘述,我也是从其他博主那里学来的

原创粉丝点击