后缀表达式求值

**

问题 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; 
} 

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

你可能感兴趣的:(课程设计之数据结构,编辑器,xp)