zoukankan      html  css  js  c++  java
  • 算术表达式的前缀,中缀,后缀相互转换

    原博客地址:https://blog.csdn.net/smartab/article/details/81215940

    中缀表达式(中缀记法)
    中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。
    虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。

    前缀表达式(前缀记法、波兰式)
    前缀表达式的运算符位于操作数之前。

    前缀表达式的计算机求值:
    从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。
    例如前缀表达式“- × + 3 4 5 6”:
    (1) 从右至左扫描,将6、5、4、3压入堆栈;
    (2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;
    (3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;
    (4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
    可以看出,用计算机计算前缀表达式的值是很容易的。
    详细解释:http://blog.csdn.net/antineutrino/article/details/6763722/

    给出一个中缀表达式如下:
    a+b*c-(d+e) 
    第一步:按照运算符的优先级对所有的运算单位加括号,
             式子变成了:((a+(b*c))-(d+e)) 
    第二步:转换前缀与后缀表达式 
             前缀:把运算符号移动到对应的括号前面 
                   则变成了:-( +(a *(bc)) +(de)) 
                   把括号去掉:-+a*bc+de   前缀式子出现 
             后缀:把运算符号移动到对应的括号后面 
                   则变成了:((a(bc)* )+ (de)+ )- 
                   把括号去掉:abc*+de+-   后缀式子出现

    <1> 将中缀表达式“1+((2+3)*4)-5”转换为前缀表达式。

    (1)构建两个栈,一个存运算符一个存操作数。运算符(以括号分界点)在栈内遵循越往栈顶优先级不降低的原则排序。

    (2)从右往左扫描中缀式表达式,从右边第一个字符开始判断。

      如果当前字符是数字,则分配到数字串的结尾并将数字串直接输出。

      如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),则将运算符直接入栈;否则将栈顶运  算符出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶元素是括号直接入栈),再将当前运算符入栈。如果是括号,则根据括号的  方向进行处理。如果是括号直接入栈;否则,遇右括号前将所有的运算符全部出栈并输出,遇右括号后将左右的两括号一起删除。

    (3)重复上述操作(2)直至扫描结束,将栈内剩余运算符全部出栈并输出,再将缀输出字符串。中缀表达式就变成了前缀表达式了。

    中缀表达式

    前缀表达式

    (栈顶)运算符栈(栈尾)

    说明

    5

    5

    5,是数字串直接输出

    -

    5

    -

    -,栈内无运算符,直接入栈

    5

    -)

    ),直接入栈

    4

    5 4

    -)

    4,是数字串直接输出

    *

    5 4

    -)*

    *,栈顶是括号,直接入栈

    )

    5 4

    - ) * )

    ),直接入栈

    3

    5 4 3

    - ) * )

    3,是数字串直接输出

    +

    5 4 3

    - ) * ) +

    +,栈顶是括号,直接入栈

    2

    5 4 3 2

    - ) * )+

    2,是数字串直接输出

    (

    5 4 3 2+

    - ) *

    (,

    (

    5 4 3 2+*

    -

    (,

    +

    5 4 3 2+*

    -+

    +,优先级大于等于栈顶运算符,直接入栈

    1

    5 4 3 2+*1

    -+

    1,是数字串直接输出

    5 4 3 2+*1+-

    扫描结束,将栈内剩余运算符全部出栈并输出

    - + 1 * + 2 3 4 5

    逆缀输出字符串

    【2】中缀表达式转换为后缀表达式

    过程和【1】差不多,只不过是从左往右扫描,方向换了一个,其他一样。

    还是这个式子:1+((2+3)*4)-5

    中缀表达式

    后缀表达式

    (栈顶)运算符栈(栈尾)

    说明

    1

    1

    1,是数字串直接输出

    +

    1

    +

    +,栈内无运算符,直接入栈

    1

    +(

    (,直接入栈

    1

    +((

    (,直接入栈

    2

    1 2

    +((

    2 ,数字

    +

    1 2

    +((+

    +,直接入栈

    3

    1 2 3

    +((+

    3,是数字串直接输出

    1 2 3 +

    +(

    碰到 )找到(之前所有符号弹出出

    *

    1 2 3 +

    +(*

    *

    4

    1 2 3 + 4

    +(*

    4

    1 2 3 + 4 *

    +

    碰到 )找到(之前所有符号弹出出

    -

    1 2 3 + 4 *

    + -

    -

    5

    1 2 3 + 4 *5

    + -

    5

    1 2 3 + 4 *5 - +

    扫描结束

    1 2 3 + 4 *5 - +

    逆缀输出字符串

    后缀表达式逆向求解中缀表达式

    1 2 3 + 4 *5 - +

    基本思路和上面的一样:递归,碰到操作符就进入递归。

    从左往右扫描先碰到+号,取+号前面两个操作数:2,3 得到:2+3.

    继续往下扫碰到*号,取4 和2+3 得到:(2+3)*4

    -号,取(2+3)*4和5得到::(2+3)*4-5

    +号:取(2+3)*4-5和1得到::1+(2+3)*4-5

  • 相关阅读:
    C++11 特色语法在 OI 中的运用
    webpack基本使用(一)
    LeetCode 887. 鸡蛋掉落 题解
    Codeforces Round #735 (Div. 2) C. Mikasa
    阿里云RDS与ECS自建mysql数据库主从同步(GTID方式)
    MySQL 5.7.x修改root默认密码
    SpringBoot引入第三方jar包或本地jar包的处理方式
    K8s 常用命令(随时更新......)
    六 Prometheus + Altermanager Email 报警
    四 Prometheus + consul
  • 原文地址:https://www.cnblogs.com/lipanDL/p/11087292.html
Copyright © 2011-2022 走看看