栈实现综合计算器

63 阅读2分钟

思路分析

1664960273403.png

代码实现

package stackArray;
​
public class Calculator {
    public static void main(String[] args) {
        String expression = "43+52*64+44-3";
        // 创建两个栈,一个符号栈,一个数字栈
        StackArray1 numStack = new StackArray1(10);
        StackArray1 operaStack = new StackArray1(10);
        int index = 0;
        int num1 = 0;
        int num2 = 0;
        int opera = 0;
        int res = 0;
        String keepNum = "";
        // 将每次扫描的的char保存起来
        char ch = ' ';
        while (true) {
            ch = expression.substring(index, index+1).charAt(0);
            if (operaStack.isOpera(ch)) {
                // 判断运算符栈是否为空,为空的话
                if (!operaStack.isEmpty()) {
                    // 判断操作符的优先级与栈顶运算符优先级高低,如果栈顶运算符优先级高,则先取出两个数字和一个运算符计算结果,将
                    // 计算结果压入数字栈,再将新运算符放入栈中,反之则直接将运算符放入栈中
                    if (operaStack.priority(operaStack.peek()) > operaStack.priority(ch) ) {
                        opera = operaStack.pop();
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        res = operaStack.cal(num2, num1, opera); // 这里要注意运算顺序
                        numStack.push(res);
                        operaStack.push(ch);
                    } else {
                        operaStack.push(ch);
                    }
                } else {
                    operaStack.push(ch);
                }
            } else {
                // numStack.push(ch-48);
                // 这样写无法识别多位数字
                // 需要加判断,需要向expression的表达式的index后再看一位,如果是数字则继续扫描,否则则入符号栈
                keepNum += ch;
                if (index >= expression.length()-1) {
                    numStack.push(Integer.parseInt(keepNum));
                } else {
                    if(operaStack.isOpera(expression.substring(index+1, index+2).charAt(0))) {
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            }
            index++;
            if(index >= expression.length()) {
                break;
            }
        }
         // 遍历结束后,循环取两个栈中的内容进行计算
        while (!operaStack.isEmpty()) {
            opera = operaStack.pop();
            num1 = numStack.pop();
            num2 = numStack.pop();
            res = operaStack.cal(num2, num1, opera); // 这里要注意运算顺序
            numStack.push(res);
        }
        int res2 = numStack.pop();
        System.out.printf("%s的运算结果为%d", expression, res2);
    }
}
class StackArray1 {
    private int top = -1;
    private int[] stack;
    private int maxsize;
    public StackArray1(int maxsize) {
        this.maxsize = maxsize;
        stack = new int[this.maxsize];
    }
    // 取出栈顶元素看一下
    public int peek() {
        return stack[top];
    }
    public boolean isFull() {
        return (this.maxsize - 1) == top;
    }
    public boolean isEmpty() {
        return top == -1;
    }
    public void push(int value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top] = value;
    }
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈空");
        }
        int temp = stack[top];
        top--;
        return temp;
    }
    public void list() {
        if (isEmpty()) {
            System.out.println("栈空");
            return;
        }
        for (int i=top; i<=0; i--) {
            System.out.printf("stack[%d]=%d", i, stack[i]);
        }
    }
    // 输入两个数字和一个运算符,将计算结果的返回
    public int cal(int a, int b, int opera) {
        int res = 0;
        switch (opera) {
            case '*':
                res = a * b;
                break;
            case '/':
                res = a / b;
                break;
            case '+':
                res = a + b;
            break;
            case '-':
                res = a - b;
            break;
        }
        return res;
    }
    // 计算运算符的优先级,返回数字越大,优先级越高
    public int priority(int ch) {
        if(ch == '*' || ch == '/') {
            return 1;
        } else if (ch == '+' || ch == '-') {
            return 0;
        } else {
            return -1;
        }
    }
    // 判断字符是否为运算符
    public boolean isOpera (int ch) {
        if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
            return true;
        } else {
            return  false;
        }
    }
}