后序表达式转化为中序表达式

一.后序表达式转化为中序表达式

后序表达式 2 3 * 2 1 - / 3 4 1 - * +  

中序表达式 ( ( ( 2 * 3 ) / ( 2 - 1 ) ) + ( 3 * ( 4 - 1 ) ) )

我们在学习数据结构的时候就知道需要用到栈

通过观察不难发现我们在后序表达式中每次遇到“+”,“-”,“*”,“/”时都要处理对应的前2个数,例如2 3 *

处理为( 2 * 3 )此时 ( 2 * 3 )就变成了一个数 可以供后面的符号处理。

这样一来我们的思路变清晰了:

即每次遇到“+”,“-”,“*”,“/”符号 就对前2个数作处理,处理后将得到的数压人栈中

如我们遇到的是数则直接压人栈中即可

因为我们是表达式转化 没有必要声明栈为double 或int的 String就可以了

我们只需要声明一个String型的名为val(val代表数值)栈

Stack<String> val = new Stack<String>();就可以了

然后对后序表达式的输入做如下处理

while(!StdIn.isEmpty()){ //当输入不为空时
    String s = StdIn.readString();
    if(s.equals("+")){ //输入为加号
        String v = val.pop();//里符号最近的数
        v=String.format("( %s %s %s )",val.pop(),s,v); //对里符号最近的2个数最处理 例如 2 3 +  v=( 2 +3 ) 
        val.push(v); //将处理后的数v=( 2+ 3)压人栈 下面3个都一样
    }
    else if(s.equals("-")){
        String v = val.pop();
        v=String.format("( %s %s %s )",val.pop(),s,v);
        val.push(v);
    }
    else if(s.equals("*")){
        String v = val.pop();
        v=String.format("( %s %s %s )",val.pop(),s,v);
        val.push(v);
    }
    else if(s.equals("/")){
        String v = val.pop();
        v=String.format("( %s %s %s )",val.pop(),s,v);
        val.push(v);
    }
    else  //如果是数值,直接压人栈
        val.push(s);



}

最后 

StdOut.println(val.pop()); //此时val栈中只有一个元素了

结果

二.中序表达式的求值

 ( ( ( 2 * 3 ) / ( 2 - 1 ) ) + ( 3 * ( 4 - 1 ) ) )

思路和上面差不多  我采用的是Dijkstar双栈法

声明2个栈 一个为String型的ops(符号)栈 另一个是Double型的val(数值)栈

Stack<Double> val =  new Stack<>();
Stack<String> ops = new Stack<>();

对上面的中序表达式从左到右依次处理

遇到“(” 我们不管 因为“(”有嵌套,我们不知道什么时候该处理

遇到数值将它压人val栈中

遇到“+”,“-”,“*”,“/”时将它压人ops栈中

遇到“)”时我们开始处理 因为一个“)”代表一个子表达式的介绍这时 我们取出第一个数 value=val.pop() 和符号ops.pop()

并令value = value +val.pop() 再把value压人val栈中 val.push(value)    注意符号是从ops中取出来的 

 

在中序表达式没有结束前依次重复上面操作

最后val栈中只剩下一个数 这个数就是结果 

代码如下

import edu.princeton.cs.algs4.*;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Evaluate {
    public static void main (String [] args){
        Stack<Double> val =  new Stack<>();
        Stack<String> ops = new Stack<>();
        while(!StdIn.isEmpty()){
            String s = StdIn.readString();
            if(s.equals("("));
            else if(s.equals("+")
                    ||s.equals("-")
                    ||s.equals("*")
                    ||s.equals("/")) ops.push(s);
            else if(s.equals(")")){
                String op = ops.pop();
                double v = val.pop();
                if(op.equals("+")) v=val.pop()+v;
                else if(op.equals("-")) v=val.pop()-v;
                else if(op.equals("*")) v = val.pop()*v;
                else if(op.equals("/")) v = val.pop()/v;
                val.push(v);
            }
            else
                val.push(Double.parseDouble(s));
        }
        StdOut.println(val.pop());
    }
}

结果

溜了溜了

 

 

 

 

 

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值