android逆波兰表达式的应用(四)逆波兰表达式的计算实现 -----小达

本文详细介绍了如何在Android平台上实现逆波兰表达式的计算,包括解析和求值过程。

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

逆波兰表达式的计算实现


        昨天写着写着就差点睡着了,,,马上就要开始复习了,连着考三门啊亲,还是不好过的三门,不过小达还是打算把逆波兰表达式的专栏写完再去复习大笑。昨天的代码没有多少,而且注释上面应该讲解的很清楚了,照着小达手动总结的规则,应该能够很容易的实现吧。今天我们就在昨天已经转化的基础上,用代码来实现逆波兰表达式的计算过程。
    
        还是那个例子
                     后缀表达式 :       9 , 3 , 2 , 1 , / , - , * , 1 , -
        
        大家应该都还记得我们在这个专栏里第二篇讲的计算规则吧。
 
     逆波兰表达式的计算其实很容易,只需要建立一个栈,里面存放数字,遇到运算符直接从数字栈里弹出数字进行计算,将结果压入栈中即可,运算完毕后,存留在数字栈中的那个数字即需要的结果.

           如规则上面说的那样,我们先建立一个数字栈,用来存放操作数,下面上栈的代码:
/**
 * 数字栈类
 */
public class MyNumStack {
    private int maxNum;           //栈的最大容量
    private String[] stackArray;  //用字符串数组来存储操作数
    private int top;              //栈顶元素的索引

    public MyNumStack(int max){
        maxNum = max;
        stackArray = new String[maxNum];
        top = -1;
    }
    public void push(String c){
        stackArray[++top] = c;
    }

    public String pop(){
        try{
            return stackArray[top--];
        }
        catch(Exception e){
            return "ERROR!";
        }
    }

    public boolean isEmpty(){
        return top == -1;
    }

}

         上面的栈和上篇博客用于转化的符号栈式差不多的,也是将数据封装好了,只给外面提供一点接口来使用,下面是用于计算的类,其中持有一个上篇博客讲到的change.java类实例,用于将中缀表达式转化为后缀表达式。
/**
 * 主要的计算类
 * 
 */
public class CalculateResult {

    private boolean num_flag = false;                           //记录是否出现了多位数
    private boolean point_flag = false;                         //记录是否出现了小数点
    private boolean hasPointFlag;                               //用来确定是有小数点

    public String cal(String str){

        Change change = new Change(str);                       //上篇博客提到过的转化类
        MyNumStack mns = new MyNumStack(str.length());         //今天讲的数字栈
        String result = change.doChange();
        hasPointFlag = result.contains(".");

        /**
         * 取出后缀表达式中的每个字符
         * 处理一遍数字
         * 再处理一遍小数点
         */
        for(int i = 0;i < result.length();i++){

            String c = result.substring(i,i+1);
            if(c.equals("_")) {
                num_flag = false;
                point_flag = false;
                continue;
            }

            try{
                dealNumber(c,mns);                                      //对数字和小数点进行逻辑盘断与处理函数
                dealOperator(c,mns);                                    //对加减乘除逻辑处理及计算函数
            }
            catch(Exception e){
                return "Error!";
            }
        }

        /**
         * 处理完之后
         * 还在数字栈里的唯一数字
         * 就是我们需要计算的结果
         */
        if(!mns.isEmpty()){
            String res = mns.pop();
            if(res.endsWith("."))
                res = res.substring(0,res.length()-1);
            if(res.endsWith(".0"))
                res = res.substring(0,res.length()-2);
            return (res);
        }
        else
            return "Error!";
    }

    /**
     * 处理数字的方法
     * 遇到小数点说明当前数字是上一个数字的低位
     * 需要将其加入到之前的那个数字中去
     */
    public void dealNumber(String c,MyNumStack mns){                             //对数字和小数点进行逻辑盘断与处理

        if(c.equals(".")||c.equals("0")||c.equals("1")||
                c.equals("2")||c.equals("3")||c.equals("4")||
                c.equals("5")||c.equals("6")||c.equals("7")||
                c.equals("8")||c.equals("9")){
                if(c.equals(".")){                                               //对小数点和数字处理
                    String top = mns.pop();
                    if(top.contains("."))
                        mns.push(top);
                    else
                        mns.push(top+".");
                    num_flag = false;
                    point_flag = true;
                }
                else {
                    if (num_flag) {
                        if(hasPointFlag){                                 //如果计算的数字里面有小数点,就用double计算,否则用integer计算

                            double re = Double.valueOf(mns.pop());
                            mns.push(String.valueOf(Math.abs(re) * 10 + Double.valueOf(c)));

                        }
                        else{
                            int re = Integer.valueOf(mns.pop());
                            mns.push(String.valueOf(Math.abs(re) * 10 + Integer.valueOf(c)));
                        }

                    }
                    else{
                        if(point_flag){
                            String a = mns.pop();
                            if(a.endsWith(".0"))
                                a = a.substring(0,a.length()-1);
                            mns.push(a+c);
                        }
                        else{
                            mns.push(c);
                            num_flag = true;
                            point_flag = false;
                        }
                    }
                }
        }
    }

    /**
     * 处理运算符的函数
     * 遇到运算符即可计算
     * 后缀表达式已经将运算的先后处理好了
     */
    public void dealOperator(String c,MyNumStack mns){
        if(c.equals("+")||c.equals("-")) {                       //遇到计算符,从栈里面弹两个数来计算,结果放回栈中
            num_flag = false;
            point_flag = false;
            String str_a = mns.pop();
            String str_b = mns.pop();
            double a = Double.valueOf(str_a);
            double b = Double.valueOf(str_b);

            if(c.equals("+"))
                mns.push(String.valueOf(b+a));
            if(c.equals("-"))
                mns.push(String.valueOf(b-a));
        }

        if(c.equals("/")||c.equals("*")) {
            num_flag = false;
            point_flag = false;

            double a = Double.valueOf(mns.pop());                //遇到计算符,从栈里面弹两个数来计算,结果放回栈中
            double b = Double.valueOf(mns.pop());
            if (c.equals("*"))
                mns.push(String.valueOf(b * a));
            if (c.equals("/"))
                mns.push(String.valueOf(b / a));
        }
    }
}

       最后在这个类中的数字栈中即为计算的结果。上面的代码是 android计算器上的一部分,在这里直接奉上全部的源码。大家可以看看哈。逆波兰表达式的专栏就到这里结束了。后面小达再有什么好东西都会和大家分享的~~~~~~再见咯
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值