数据结构与算法(八)两个栈计算简单的整数四则运算表达式

上一篇我们练习了怎么手动实现一个简单的栈式结构,这一次我们通过自己实现的栈,来解决简单的四则运算表达式的计算问题。

首先贴出栈的代码:

public class MyStack {
    /**
     * 栈结构和ArrayList结构差不多,但它只有一个入口兼出口,不允许随机访问,也就是先进后出FIFO
     */
    private String[] dataArray;
    private int size;
    public MyStack(){
        dataArray=new String[8];
        size = 0;
    }

    //入栈
    public void push(String data){
        if(size>=dataArray.length){
            //如果数组已满则需要先扩容
            String[] tempArray = new String[size*2];
            for(int i = 0;i<dataArray.length;i++){
                tempArray[i]= dataArray[i];
            }
            dataArray=tempArray;
        }
        dataArray[size]=data;
        size++;
    }

    //出栈
    public String pop(){
        if(size>0){
            String o = dataArray[size-1];
            System.out.println(o+"出栈");
            dataArray[size-1]=null;
            size--;
            return o;
        }else{
            System.out.println("栈已空,无元素可出");
            return null;
        }
    }

    //获取栈顶元素,不出栈
    public String peek(){
        if(size>0){
            return dataArray[size-1];
        }else{
            System.out.println("栈已空");
            return null;
        }
    }

    public int size(){
        return size;
    }

    public void print(){
        for(int i=0;i<size;i++){
            System.out.println(dataArray[i]);
        }
    }

    /*为了方便取出算术表达式的结构,
    我这里写了一个取出字符数组的方法,
    正常来讲栈不应该有这个方法才对*/
    public String[] getArray(){
        return dataArray;
    }
}

接下来我们写一个测试方法,来使用栈计算运算表达式的值

public class Test01 {
    public static void main(String[] args){

        //使用两个栈模拟运算简单的整数四则运算表达式,
        //很初级,只考虑整数,不考虑小数,感兴趣的同学可以自己完善
        String str = "31+24*15-176/11";
        String jia = "+";
        String jian = "-";
        String cheng = "*";
        String chu = "/";
        //下面这两个todo是对程序健壮性的优化,不是本次练习的重点,我就不写了
        //todo 如果算术表达式中含有运算符和数字以外的字符,则报错
        //todo 如果相邻两个字符都是运算符,则报错
        MyStack stack1 = new MyStack();//存数字
        MyStack stack2 = new MyStack();//存运算符
        String[] strings = splitToArray(str);
        //先算乘除运算
        for(int i=0;i<strings.length;i++){
            if(null!=strings[i]){
                if(isDigit(strings[i])){
                    if(cheng.equals(stack2.peek())||chu.equals(stack2.peek())){
                        String yunsuanfu = stack2.pop();
                        String num1s = stack1.pop();
                        Double num1=Double.valueOf(num1s);
                        Double num2 = Double.valueOf(strings[i]);
                        if(cheng.equals(yunsuanfu)){
                            Double tempResult = num1*num2;
                            stack1.push(String.valueOf(tempResult));
                        }else{
                            Double tempResult = num1/num2;
                            stack1.push(String.valueOf(tempResult));
                        }
                    }else{
                        stack1.push(strings[i]);
                    }
                }else{
                    stack2.push(strings[i]);
                }
            }
        }
        //后算加减运算
        while(null!=stack2.peek()){
            String yunsuanfu=stack2.pop();
            String num2s = stack1.pop();
            Double num2 = Double.valueOf(num2s);
            String num1s = stack1.pop();
            Double num1 = Double.valueOf(num1s);
            if(jia.equals(yunsuanfu)){
                Double tempResult= num1+num2;
                stack1.push(String.valueOf(tempResult));
            }else{
                Double tempResult= num1-num2;
                stack1.push(String.valueOf(tempResult));
            }
        }
        System.out.println(stack1.peek());
    }

    //将运算表达式字符串分解成数字和运算符的形式,便于下面的计算
    public static String[] splitToArray(String str){
        MyStack stack= new MyStack();
        boolean lastOneIsDigit = true;
        for(int i = 0;i<str.length();i++){
            if(Character.isDigit(str.charAt(i))){
                if(i==0){
                    stack.push(String.valueOf(str.charAt(i)));
                }else{
                    if(lastOneIsDigit){
                        String lastDigitStr = stack.pop();
                        double lastDigit = Double.parseDouble(lastDigitStr);
                        stack.push(String.valueOf(lastDigit*10+ Double.parseDouble(String.valueOf(str.charAt(i)))));
                    }else{
                        stack.push(String.valueOf(str.charAt(i)));
                        lastOneIsDigit=true;
                    }
                }
            }else{
                stack.push(String.valueOf(str.charAt(i)));
                lastOneIsDigit = false;
            }
        }
        return stack.getArray();
    }

    //使用正则表达式判断一个字符串是不是数字
    public static boolean isDigit(String str){
        return str.matches("-?\\d+(\\.\\d+)?");
    }

}

最后我们运算测试类,可以得到表达式的值上375

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值