多位数运算表达式回顾

我的复习代码:

package stack;

public class Calculate2 {
    public static void main(String[] args) {
        //中缀表达式的计算思路
        String expression = "72*4-51+12/4";
        //建造两个栈,分别为数栈和符号栈,用于存放数和符号
        Stack2 ns = new Stack2(20);
        Stack2 ss = new Stack2(20);
        //对表达式进行扫描,数字,直接入栈
        char ch = ' ';      //接收带扫描的字符
        String keepNum = "";        //针对对位数相加减的拼接
        int index = 0;          //用于扫描索引
        int res = 0;           //用于存放结果
        while (true){
            ch = expression.charAt(index);
            System.out.println("每一次扫描开始的ch值" + ch);
            if(!ss.isOper(ch)){
              //  System.out.println(ch);
                //情况一,不是符号是数字,直接入栈
                //针对多位数,进行拼接
                keepNum += ch;
                System.out.println("进入判断之前的keepNum" + keepNum);
                if(index == (expression.length() - 1)){
                    //不在拼接的情况一,已经到了字符串的末尾
                    ns.push(Integer.parseInt(keepNum));
                    System.out.println(Integer.parseInt(keepNum));
                    keepNum = "";
                }else if(ss.isOper(expression.charAt(index + 1))){
                    ns.push(Integer.parseInt(keepNum));
                    keepNum = "";
                }

            }else{
                //情况二不是数字是符号
                if(ss.isEmpty()){
                    //符号总共是两种情况:情况一,如果是符号栈为空,直接入栈;
                    ss.push(ch);
                    //System.out.println(ch);
                }else if(ss.priority(ss.top()) < ss.priority(ch)){
                    // 如果符号栈不为空,按照优先等级分为两种情况,
                    // 情况二,待入栈的符号优先级大于栈内top符号,就直接入栈
                    ss.push(ch);
                    //System.out.println(ch);
                }else{
                    // 情况一,待入栈的符号优先级小于或者是等于栈内top符号,就从数栈里面弹出两个数,符号栈里面弹出一个符号,
                    // 运算,值入数栈,未入栈的符号入栈
                    int num1 = ns.pop();
                    int num2 = ns.pop();
                    res = ss.cal(num1,num2,ss.pop());
                    ns.push(res);
                    //System.out.println(res);//注意啊,每一次都忘记入栈,然后花很大劲去查
                    ss.push(ch);
                    //System.out.println(ch);
                }
            }
            index ++;
            System.out.println("index:" + index);
            //注意index的位置每一次要用的原值的话,就放在最后
            if(index == (expression.length())){
                break;
                //跳出循环的条件
            }
        }
        while (true) {
            int num1 = ns.pop();
            int num2 = ns.pop();
            res = ss.cal(num1,num2,ss.pop());
            ns.push(res);
            //循环截至,符号栈为空就是了
            if(ss.isEmpty()){
                break;
            }
        }
        System.out.println(expression + " = " + ns.pop());
        //扫描完毕之后在一次运算,数栈里面最后的书就是结果

    }
}
class Stack2 {
    //栈必须有头指针,数组模拟,最大空间,数组初始化
    int top = -1;
    int maxSize;
    int[] stack;

    public Stack2(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[maxSize];
    }

    //栈基本的方法,是否为空,是否为满,pop和push,以及show验证
    public boolean isEmpty() {
        //栈验证是否为空,top是否等于-1
        return top == -1;
    }

    public boolean isFull() {
        //栈是否为满,top == maxSize-1
        return top == (maxSize - 1);
    }

    public void push(int m) {
        //往栈里面压入元素,top上移,数组赋值
        //入栈之前要判定是否为满
        if(isFull()){
            System.out.println("栈已满");
            return;
        }
        top++;
        stack[top] = m;
    }

    public int pop() {
        //元素出栈,中间变量取值,top--
        //出栈,要判定栈是否为空
        if(isEmpty()){
            System.out.println("栈已空");
            return -1;
        }
        int temp = stack[top];
        top--;
        return temp;
    }

    public void show() {
        //显示栈内部的元素,并不是出栈
        for (int i = top; i >= 0; i--) {
            System.out.println("stack[" + i + "]=" + stack[i]);
        }
    }
    public int top(){
        return stack[top];
    }

    //故而根据上情况要建立判断优先级的方法
    public int priority(int ch) {
        if (ch == '*' || ch == '/') {
            return 1;
        } else if (ch == '+' || ch == '-') {
            return 0;
        } else {
            return -3;
        }
    }

    // 判断是否为符号的方法,
    public boolean isOper(char ch) {
        return ch == '*' || ch == '/' || ch == '+' || ch == '-';
    }

    // 运算的方法
    public int cal(int num1, int num2, int ch) {
        int res = 0;
        if (ch == '*') {
            res = num1 * num2;
            System.out.println(num1  + "*" + num2 + "=" + res);
            return res;
        } else if (ch == '/') {
            res = num2 / num1;
            System.out.println(num2  + "/" + num1 + "=" + res);
            return res;
        } else if (ch == '+') {
            res = num2 + num1;
            System.out.println(num1  + "+" + num2 + "=" + res);
            return res;
        } else if (ch == '-') {
            res = num2 - num1;
            System.out.println(num2  + "-" + num1 + "=" + res);
            return res;
        }else{
            return 0;
        }
    }

}

问题

  1. 空指针异常
  • 解答:出栈入栈忘记判断栈空还是栈满,逻辑不清晰;不index++的迭代条件,放在了开头,导致后来重复使用的index都是错的,结果是中不正确
  1. 多位数读取失败,读取不了第二位
  • 解答:说明拼接失败,误把keepNum的清空语句和拼接语句放到了同一个代码块,自然而然地就出现了拼接失败
  1. 出现空栈的异常!
  • 扫描索引错误,致使符号栈正常,但是数栈少了一位,最后一位没有扫描进去

我居然不会debug!!!!!好像该犯的都犯了!!

发布了19 篇原创文章 · 获赞 3 · 访问量 619

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/103831452