zoukankan      html  css  js  c++  java
  • 表达式求值与后缀表达式

    转载请注明出处:http://www.cnblogs.com/luna-lovegood/archive/2012/07/17/2596501.html

     一个算术表达式,含有数字(为简化处理,数字只有一位),运算符:+-*,以及括号,求表达式的值。

     给出的表达式是一般我们见到的中缀表达式,即运算符位于操作数之间。如果把中缀表达式转化为后缀表达式,那么对后缀表达式求值将会很方便。

     后缀表达式特点

      1.操作符位于操作数之后;

      2.没有括号;

      3.运算符没有优先级。

     中缀表达式转化为后缀表达式的步骤

      1.初始化一个空操作符栈和空结果字符串;

      2.从前到后读取中缀表达式的字符,如果是操作数,加到结果字符串后面;

      3.如果是操作符,分两种情况入栈:

        a.如果待入栈操作符优先级大于栈顶操作符,直接入栈;

        b.如果待入栈操作符优先级小于或等于栈顶操作符,栈顶操作符加到结果字符串后面;重复b过程直到遇到前括号‘(’或栈顶操作符优先级比待入栈操作符小,待入栈操作符入栈。

      4.如果是前括号‘(’,直接入栈;

      5.如果是后括号,将栈中操作符依次弹出,直至遇到一个前括号‘(’结束。前括号出栈。

      最后结果字符串就是后缀表达式。

      后缀表达式求值的步骤

      1.初始化一个空操作数栈;

      2.从前到后读取后缀表达式字符。如果是操作数直接入栈。如果读到一个操作符@,弹出栈顶元素a和新的栈顶元素b,执行b @ a,将结果压入栈中;

      3.最后栈中只剩下一个元素,即表达式的值。

     

      关于中缀表达式转换成后缀表达式与后缀表达式正确性的说明

      先观察一些例子:

      1.假设中缀表达式没有括号,且所有运算符优先级相同。比如a+b-c+d-e+f ,将被转化为ab+c-d+e-f+。此时用括号来说明后缀表达式执行顺序:((((( ab+ ) c- ) d+ ) d- ) f+ ),运算顺序没有改变。

      2.假设中缀表达式没有括号,但是运算符优先级不同。比如a+b*c+d-e*f,将被转化为 abc*+d+ef*-,用括号来说明后缀表达式执行顺序:((( a ( bc* ) + ) d+ ) ( ef* ) - ),运算顺序依然没有变。

      3.假设中缀表达式有括号。比如(a+b)*(c+d)*e+f,将被转化为ab+cd+*e*f+,用括号表示执行顺序(((( ab+ ) ( cd+ ) * ) e* ) f+ )。运算顺序还是没有改变。

     

      不难观察出以下5点

      1.后缀表达式中操作数出现的顺序和中缀表达式一样。这是因为操作数是直接加入结果字符串;

      2.每个操作符都会入栈一次,出栈一次;

      3.在没有括号时,如果相邻两个操作符优先级相同或前一个操作符的优先级高,则后缀表达式中操作符出现的顺序和中缀表达式一样。因为后一个操作符入栈时,栈顶元素一定是前一个相邻的操作符,如果其优先级小于等于待入栈的,则前一个操作符被弹出并加入结果字符串,后缀表达式中操作符顺序得到保持。

      4.在没有括号时,如果相邻两个操作符,后者优先级大与前者,后者将直接被压入栈中,且位于前者之上。在出栈时,后者将先出栈,因而后缀表达式中,操作符顺序发生交换,即中缀表达式中要先运算的操作在后缀表达式中出现在前面。

      5.出现括号。括号中的处理因为遵循前4点,不再赘述,而括号的内容作为一个整体的性质得到维护。

      参考文章:

      http://blog.csdn.net/daheiantian/article/details/6553713

      http://blog.csdn.net/niushuai666/article/details/6702964

      http://www.cnblogs.com/luna-lovegood/archive/2012/07/17/2596464.html

    代码:

     1 //zzy2012.7.17
     2 //利用后缀表达式对算数表达式求值
     3 //不含符号变量处理,且数字都是一位,运算符仅含+、-、*和括号
     4 #include<cstdio>
     5 #include<iostream>
     6 #include<cstring>
     7 #define NUM 200
     8 
     9 using namespace std;
    10 
    11 char s[NUM],a[NUM],stack[NUM];
    12 int stacknum[NUM];
    13 
    14 int trans(char s[NUM],char a[NUM],char stack[NUM],int lens){
    15     int lena = 0,top = 0;
    16     for(int i=0; i<lens; i++){
    17         if(s[i]>='0' && s[i]<='9'){
    18             a[lena++] = s[i];
    19         }
    20         else if(s[i]=='+' || s[i]=='-'){
    21             while(top>0 && stack[top-1]!='(')
    22                 a[lena++] = stack[--top];
    23             stack[top++] = s[i];
    24         }
    25         else if(s[i] == '*'){
    26             while(top>0 && stack[top-1]!='(' && stack[top-1]!='+' && stack[top-1]!='-')
    27                 a[lena++] = stack[--top];
    28             stack[top++] = s[i];
    29         }
    30         else if(s[i]=='(')
    31             stack[top++] = s[i];
    32         else if(s[i]==')'){
    33             while(top>0 && stack[top-1]!='(')
    34                   a[lena++] = stack[--top];
    35             top--;
    36         }
    37     }
    38     while(top>0){
    39         a[lena++] = stack[--top];
    40     }
    41     return lena;
    42 }
    43 
    44 int calcu(char a[NUM],int stack[NUM],int lena){
    45     int top=0;
    46     for(int i=0; i<lena; i++)
    47         if(a[i]>='0' && a[i]<='9')
    48             stack[top++] = a[i]-'0';
    49         else{
    50             if(a[i]=='+')
    51                 stack[top-2] = stack[top-2] + stack[top-1];
    52             else if(a[i] == '-')
    53                 stack[top-2] = stack[top-2] - stack[top-1];
    54             else if(a[i]=='*')
    55                 stack[top-2] = stack[top-2] * stack[top-1];
    56             top--;
    57         }
    58     return stack[0];
    59 }
    60 
    61 int main()
    62 {
    63     int ans,lens,lena;
    64     gets(s);
    65     lens = strlen(s);
    66     lena = trans(s,a,stack,lens);//将中缀表达式转换横后缀表达式,返回值是后缀表达式a的长度
    67     ans = calcu(a,stacknum,lena);//计算后缀表达式值
    68     printf("%d\n",ans);
    69     return 0;
    70 }
  • 相关阅读:
    jQuery的实用技巧
    jQuery中的Ajax
    jQuery中的动画
    jQuery中的事件
    jQuery中的DOM操作
    详解jQuery的选择器
    微信小程序开发教程(九)视图层——.wxss详解
    微信小程序开发教程(八)视图层——.wxml详解
    14 组合查询
    13 创建高级联结
  • 原文地址:https://www.cnblogs.com/Lattexiaoyu/p/2596501.html
Copyright © 2011-2022 走看看