zoukankan      html  css  js  c++  java
  • 波兰表达式

      1 波兰式也叫后缀表达式(postfix)(将运算符写在操作数之后),相应的波兰表达式叫前缀表达式(运算符在操作数之前)。

    中缀表达式(infix)是我们最常使用的。

    如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+

    (a+b)*c-(a+b)/e的后缀表达式为:
    (a+b)*c-(a+b)/e
    =>
    ((a+b)*c)((a+b)/e)-
    =>
    ((a+b)c*)((a+b)e/)-
    =>
    (ab+c*)(ab+e/)-
    =>
    ab+c*ab+e/-

    2 你可以把一个多项式写成树的形式,比如你上面的式子:
    -
    / \
    * /
    / \ / \
    + c + e
    / \ / \
    a b a b
    / /波兰式就是这棵树的后序遍历结果。
    / /而这棵树的前序遍历就是波兰表达式,即前缀表达式

    中缀表达式我们有时需要添加括号来区别不同的计算顺序。但是括号在前缀和后缀中是不需要的

    把后缀表达式变成中缀表达式:我们把2个操作数后面跟着一个操作符的事件替换成对应的中缀表达式,加上括号来指出所得结果可以被看成新的操作数。也就是说,当表达式中出现ab*和ab+时,将他们分别替换成(a*b)和(a+b);然后我们队结果表达式做同样的变换,一直继续直到所有的操作符都已经被处理过。

    5  9  8  +  4  6  *  *  7  +  *

    5 (9+8) (4*6) *7  + *

    5 ( (9+8)*(4*6))7 +*

    5( (9*8)*(4*6))+7)*

    (5 * ( (9*8)*(4*6))+7)  )

     用这种方法,我们能够决定后缀表达式中的操作数到底跟哪个操作符关联,因此不需要任何括号

     在栈的帮助下,我们能对任意的后缀表达式进行求值操作。从左往右处理:遇到一个操作数,把它推入栈中,遇到一个操作符,弹出栈中的两个数,执行所示操作,将结果推入栈

    /*求解波兰表达式的值*/
    输入数据:
    输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数
    输出要求:
    输出为一行,表达式的值。
    
    #include <iostream>
    #include <cstdlib>
    using namespace std;
    double exp() //返回波兰表达式的值
    {
    
    char a[10]; //用于存储第一个非空格字符
    cin >> a;.
    switch(a[0])
    { //递归的思想,需要好好理解。。。
    case '+': return exp() + exp();
    case '-': return exp() - exp();
    case '*': return exp() * exp();
    case '/': return exp() / exp();
    default : return atof(a); //将字符串转化成浮点数
    }
    
    }
    int main()
    {
    freopen( "in.txt", "r", stdin );
    freopen( "out.txt", "w", stdout );
    cout << exp() << endl;//以后要把精度控制加上
    return 0;
    }
     

    逆波兰表达式优点:

     它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:

      如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果
     
    中缀转后缀:
    用堆栈解析算术表达式的过程

    中缀表达式翻译成后缀表达式的方法如下:

    (1)从右向左依次取得数据ch。

    (2)如果ch是操作数,直接输出。

    (3)如果ch是运算符(含左右括号),则:
          a:如果ch = '(',放入堆栈。
          b:如果ch = ')',依次输出堆栈中的运算符,直到遇到'('为止。
          c:如果ch不是')'或者'(',那么就和堆栈顶点位置的运算符top做优先级比较。
              1:如果ch优先级比top高,那么将ch放入堆栈。
              2:如果ch优先级低于或者等于top,那么输出top,然后将ch放入堆栈。

    (4)如果表达式已经读取完成,而堆栈中还有运算符时,依次由顶端输出。

    如果我们有表达式(A-B)*C+D-E/F,要翻译成后缀表达式,并且把后缀表达式存储在一个名叫output的字符串中,可以用下面的步骤。

    (1)读取'(',压入堆栈,output为空
    (2)读取A,是运算数,直接输出到output字符串,output = A
    (3)读取'-',此时栈里面只有一个'(',因此将'-'压入栈,output = A
    (4)读取B,是运算数,直接输出到output字符串,output = AB
    (5)读取')',这时候依次输出栈里面的运算符'-',然后就是'(',直接弹出,output = AB-
    (6)读取'*',是运算符,由于此时栈为空,因此直接压入栈,output = AB-
    (7)读取C,是运算数,直接输出到output字符串,output = AB-C
    (8)读取'+',是运算符,它的优先级比'*'低,那么弹出'*',压入'+",output = AB-C*
    (9)读取D,是运算数,直接输出到output字符串,output = AB-C*D
    (10)读取'-',是运算符,和'+'的优先级一样,因此弹出'+',然后压入'-',output = AB-C*D+
    (11)读取E,是运算数,直接输出到output字符串,output = AB-C*D+E
    (12)读取'/',是运算符,比'-'的优先级高,因此压入栈,output = AB-C*D+E
    (13)读取F,是运算数,直接输出到output字符串,output = AB-C*D+EF
    (14)原始字符串已经读取完毕,将栈里面剩余的运算符依次弹出,output = AB-C*D+EF/-

    5 计算算术表达式

    当有了后缀表达式以后,运算表达式的值就非常容易了。可以按照下面的流程来计算。

    (1)从左向右扫描表达式,一个取出一个数据data
    (2)如果data是操作数,就压入堆栈
    (3)如果data是操作符,就从堆栈中弹出此操作符需要用到的数据的个数,进行运算,然后把结果压入堆栈
    (4)如果数据处理完毕,堆栈中最后剩余的数据就是最终结果。
    http://www.cnblogs.com/dolphin0520/p/3708602.html
    http://blog.csdn.net/luo6620378xu/article/details/8629127
    http://blog.csdn.net/arduousbonze/article/details/3128084

     深入:

    http://www.360doc.com/content/07/0517/16/27670_505362.shtml

    http://www.360doc.com/content/11/0719/19/28217_134555693.shtml

     

     

     

  • 相关阅读:
    php hook example
    sql 建立数据库,表格,索引,主键
    js 高级函数 之示例
    js 事件
    DOM 操作内容 innerText/innerHTML
    DOM 之 document 查找元素方法
    BOM 之 screen history
    Hadoop源码篇--Client源码
    Spark算子篇 --Spark算子之combineByKey详解
    Pandas库的使用--Series
  • 原文地址:https://www.cnblogs.com/youxin/p/2615716.html
Copyright © 2011-2022 走看看