前缀式中缀式后缀式笔记

本文详细介绍了前缀式、中缀式和后缀式算术表达式,以及如何进行中缀式到后缀式的转换。通过定义符号栈和数字栈,遵循特定的进栈出栈规则,将3+4-5+(4*1)等表达式转换为后缀式。同时,文中还探讨了中缀式转换为前缀式的方法,以及前缀式在计算器运算中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                  缀式的相互转换

1.先了解什么事是前缀式,中缀式,后缀式
定义:这三种表达式其实就是算术表达式的三种写法,以 3+4-5为例
  前缀式: 操作符在操作数前面 3+(4-5) -> +3-45(没有括号就3+4-5 前缀式:+-345 这样算结果不对,百度下,还是不太清楚)(可能是同等级优先级是要加一个括号括起来呢)
  中缀式: 操作符在操作数中间 3+4-5 ->平常我们所熟悉的运算表达式
  后缀式: 操作符在操作数后面 34+5- ->计算机计算就是用后缀式(不唯一)

2.中缀式转换为后缀式(计算机运算实现)
  3+4-5
  定义两个栈:符号栈(存放操作符),数字栈(存放数字和运算结果).
  
  符号栈:定义运算符号的优先级,这个可以设置一个int类型变量实现
         +,-定义优先级最低
     *,/,% 定义优先级次低
         ^ 定义优先级最高
     
         
         中缀式转换为后缀式只要一个符号栈就可以了,数字栈是解释计算机工作原理的,
     算数表达式是要String类型,String类型转换为char数组

     符号栈的进栈出栈规律:1.当遍历数组的时候遇到数字字符,则直接保存
                  2.当遇到符号字符时:当栈空是就直接进栈;否则就判断栈顶的运算符的优先级是否小于要进栈的符号
                            (记住是小于,等于或是大于都不行)
                              3.当栈顶符号优先级大于要进栈符号,则栈顶符号出栈,出栈符号保存,当下一个栈顶符号还是
                    优先级大于要进栈元素,则继续栈顶出栈,保存栈顶符号,直到要进栈符号满足进栈要求进栈为止
                              4.当进栈符号是左括号(时直接进栈
                  5.当进栈符号是右括号)时,一直出栈,知道遇到符号是左括号为止,出栈符号保存,左括号出栈不保存
                  6.当遍历完数组的时候就出栈所有符号,保存

                  3+4-5+(4*1)进栈过程 -> 保存使用StringBuffer s来,符号找用f来表示
                  
                  1.遍历时遇到数字直接保存
                                s = 3,f = 空
                  2.遍历时遇到符号字符+号
                    这时符号栈为空,直接进栈
                s = 3,f = +
                  3.遍历时遇到数字直接保存
                    s = 34,f = +
                  4.遍历时遇到符号字符-号
                    这时符号栈的栈顶符号是+号,+号的优先级和-号一样,进栈要求是要进栈符号优先级要大于栈顶符号
                那么就要出栈+号,出栈后符号栈为空,符号栈为空就直接-号进栈
                s = 34+,f = -
                  5.遍历时遇到数字直接保存
                    s = 34+5,f = -
                  6.遍历时遇到左括号,直接进栈
                    s = 34+5-,f = +("左括号为栈顶"
                  7.遍历时遇到符号*
                    符号*优先级是比+,-高但是栈顶是左括号,那是否进栈呢?
                    答:遇到左括号直接进栈,不考虑左括号优先级,左右括号的优先级是最低的,但不要去设置
                    为什么不进行设置?因为会引起冲突,
                    什么冲突?当1+1(1*1)时
                    +进栈为栈顶,优先级是比(左括号高,则是否进栈呢?
                    当然进栈,可是违背了符号栈进栈规律,是的,这就是冲突了,所以就
                不要设置,直接自己默认知道就行,也可以麻烦一点多设置几个判断条件解决
                反正我是没试过.

                    s = 34+5-,f = +(
                s = 34+5-41,f = +(*
                s = 34+5-41*+,f = +(*

                  8.遍历时遇到右括号时,不进栈,直接出栈栈顶符号,直到栈顶符号是左括号
                    这里栈顶是*号,出栈,出栈后栈顶符号是左括号,停止循环出栈.这时的栈顶符号
                是左括号,这里是要出栈的,为什么上面不直接把左括号一起出栈得了,回答:这样循环退出条件
                如何设置,这样想?不是左括号的时候就退出出栈循环?那这循环就是费了,循环退出条件得符号是
                左括号的时候,退出出栈循环后还要进行一次出栈,不过这次出栈得是有条件的,就是左括号的时候,
                为了防止有其他情况而胡乱出栈的情况,左括号和右括号都是不保存的
                s = 34+5-41* f = +
                              9.数组遍历结束,循环出栈符号栈所有的符号了
                    s = 34+5-41*+ f = 空
                  
                  34+5-41*+就是后缀式了,有人可能问了,和上面的例子不一样呀,也和定义有所不同
                  那行,使用3+4-5变成后缀式看看
                  s = 3 , f = 空
                  s = 3 , f = +
                  s = 34 , f = +
                  s = 34+ , f = -
                  s = 34+5 , f = -
                  s = 34+5- , f = 空
                  有括号就不理解了肯定是不行的

                              
     使用数字栈的时候是已经把中缀式转换为后缀式了,这是用后缀式来进行的操作
     数字栈的进栈出栈规律: s = 34+5-41*+
                   1.把StringBuffer使用toString方法转换为String类型,再转换为char数组
               2.遍历数组,当遇到数字字符直接进数字栈
               3.当遇到符号字符时(一般情况下是数字栈数字是等于或超过两个的,不然就是后缀式错误)
                 ,编写一个方法,功能是根据符号字符判断运算符,并接收数字栈的栈顶数字和次栈顶数字,返回栈顶数字和次栈顶数字的运算结果
             这里注意:进行减运算时,次栈顶数字-栈顶数字,除和模运算也是次栈顶数字/(%)栈顶数字
                 把运算结果进栈
                       4.一直循环做2~3步,知道char数组遍历完成后就出栈最终运算结果
                 基本是每两个数字进行一次运算,再把运算结果进栈,又变成了两个数字进行运算

             34+5-41*+

             数字栈用m表示 ,运算过程用t表示(随意)
             m = 34  t = 无
             遇到符号+字符,进行方法判断
             if('+' == 字符数组[i]){
                int k = m.出栈 - '0';
                int j = m.出栈 - '0';
                return k+j;
             }
             if('/' == 字符数组[i]){
                int k = m.出栈 - '0'; 栈顶数字
                int j = m.出栈 - '0'; 次栈顶数字
                return j/k;
             }
             注意:只有减法,除法模运算才很注意数的左右位置(就是除数与被除数关系)
                         m = 3 4 ,t = 3+4
             m = 7 , t = 无
             m = 7 5 ,t = 无
             遇到符号-字符,进行方法判断
             m = 7 5 ,t = 7-5
                         m = 2 , t =无
             34+5-41*+变成了241*+
                         遇到符号*字符,进行方法判断
             m = 2 4 1 , t = 4*1
             m = 2 4 , t = 无
             遇到符号+字符,进行方法判断
             m = 2 4 , t = 2+4
             m = 6
             最后栈中是最后的运算结果:3+4-5+(4*1)=6

3.中缀式转换前缀式,从从右往左开始扫描中缀式
  同上定义两个栈,一个数字栈,一个符号栈,和运算符的优先级,级别同上
  String类型的数学运算表达式转换为char数组,循环,循环反向,i--嘛,懂!就是下标等于数组长度,然后自减;
  
  符号栈用f表示,保存用StringBuffer类型的s表示
  符号栈进栈出栈规则:
          1.当遇到数字字符时,直接保存
      2.当遇到符号字符时,符号栈为空栈直接进栈;
        当栈顶符号优先级小于等于要进栈符号则进栈(要进栈符号优先级要大于等于栈顶符号);
        (这里就是与上面第二个不同点了,第一个不同点就是扫面方向各自不同)
        当栈顶符号优先级大于要进栈符号则循环出栈,直到满足优先级大于等于栈顶符号或栈空
          3.当遇到右括号时直接进栈 
        当遇到左括号时循环出栈,直到栈顶符号是右括号      ->这里就是与上面第三个不同点
        同样不保存左右括号,出栈栈顶符号为右括号时停止,然后弹出右括号
          4.数组循环结束后出栈所有符号并保存  
           
       3+4-5+(4*1)

       从右开始到最左结束
       1.遇到右括号直接进栈
       s = 空 , f = )
       2.遇到数字,直接保存
       s = 1 , f = )
       3.遇到*号,判断优先级,判断可以进栈
       s = 1 , f = )*
       4.遇到数字,直接保存
       s = 14 , f = )*
       5.遇到左括号(,循环出栈,直到栈顶为右括号时停止,然后再一次出栈去掉右括号
       s = 14* , f = 空
       6.遇到+号,空栈,直接进栈
       s = 14* , f = +
       7.遇到5
       s = 14*5 , f = +
       8.遇到-号,优先级等于+号,进栈
       s = 14*5 , f = +-
       9.遇到4
       s = 14*54 , f = +-
       10.遇到+,优先级等于-,进栈
       s = 14*54 , f = +-+
       11.遇到3
       s = 14*543 , f = +-+
       12.数组遍历结束,出栈所有并保存
       s = 14*543+-+ , f = 空
       前缀式: +-+345*41
       (没错,反过来,本来是使用一个普通栈进行保存出栈符号的,但让本人自己更好理解嘛都一样)

           计算器使用前缀式进行运算

       数字栈m表示,过程t表示
       规律:大体同上,就是扫描不是从左往右,而是从右往左;这里是栈顶数字 -(/,%) 次栈顶数字
            遇到数字就进栈,遇到符号就判断进行什么运算
           +-+345*41
       1. m = 14 , t = 无
       2. m = 14 , t = 4*1 -> 栈顶数字:运算符号:次栈顶数字
       3. m = 4 , t = 无
       4. m = 4543 , t = 3+4 
       5. m = 457 , t = 7-5
       6. m = 42 , t = 2+4
       7. m = 6
       出栈得结果
       3+4-5+(4*1)= 6

            
  
                        

    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值