【数据结构与算法(Java)】计算器(中缀表达式实现)

1. 中缀计算器

public class InfixCalculator {

    /**
     * @author - hoy
     * 计算器:计算所给出数学表达式字符串的结果,返回结果值(只计算个位数的数字输入,无括号)
     * @param expression - 表达式字符串
     * @return - 返回计算结果
     */
    public static int infixCalculator(String expression) {
        // 1. 若字符串为空或null,抛出异常
        if (expression == null || expression.isEmpty()) {
            throw new RuntimeException("null or empty");
        }

        // 2. 设置两个栈,一个储存数字,一个储存运算符号
        ArrayStack2 digitStack = new ArrayStack2(expression.length());
        ArrayStack2 operatorStack = new ArrayStack2(expression.length());
        // 3. 设置必要的变量
        int number1 = 0;
        int number2 = 0;
        int operator = 0;
        int result = 0;
        String wholeNumber = "";

        // 4. 遍历expression,逐个处理字符
        for (int i = 0; i < expression.length(); i++) {
            // 4.1 获取当前字符
            char currentChar = expression.charAt(i);

            // 4.2 若为 运算符
            if (ArrayStack2.isValidOperator(currentChar)) {
                // 4.2.1 当运算符栈非空 且 栈顶为'*'时,开始循环计算栈内现有的乘法(因为只要遇到'/'就计算了,所以只会有'*'
                while (!operatorStack.isEmpty() && operatorStack.peekTop() == '*') {
                    // (1) 数字栈取两个数字,取出栈顶字符
                    number1 = digitStack.pop();
                    number2 = digitStack.pop();
                    operator = operatorStack.pop();
                    // (2) 若运算符栈非空
                    if (!operatorStack.isEmpty()) {
                        // 若两个字符同级,若前一个字符为"-",则改当前字符为同级的另一字符
                        operator = ArrayStack2.changeOperator(operator, operatorStack.peekTop());
                    }
                    // (3) 计算结果
                    result = ArrayStack2.calculator(number1, number2, operator);
                    // (4) 结果入数字栈
                    digitStack.push(result);
                }

                // 4.2.2 当前字符入运算符栈
                operatorStack.push(currentChar);
            }
            // 4.3 若为 数字:直接入数字栈(但要做"数字拼接"处理)
            else if (digitStack.isValidNumber(currentChar)) {
                // 4.3.1 拼接到 wholeNumber
                wholeNumber += currentChar;
                // 4.3.2 若expression已经到达末尾 或者 expression的下一字符为 运算符:将wholeNumber入数字栈,并清空wholeNumber
                if (i == expression.length() - 1 || ArrayStack2.isValidOperator(expression.charAt(i + 1))){
                    digitStack.push(Integer.parseInt(wholeNumber));
                    wholeNumber = "";
                }
                // 4.3.3 判断前一运算符是否为'/',若是,先计算,并将结果放入数字栈
                if (!operatorStack.isEmpty() && operatorStack.peekTop() == '/') {
                    operatorStack.pop();
                    number1 = digitStack.pop();
                    number2 = digitStack.pop();
                    result = number2 / number1;
                    digitStack.push(result);
                }
                // 4.3.4 否则继续遍历expression
            }
        }

        // 5. expression 扫描完毕,依次pop出两个栈的数字和运算符,计算结果,当运算符栈为空时停止
        while (!operatorStack.isEmpty()) {
            // 5.1 数字栈取两个数字,取出栈顶字符,计算出结果
            number1 = digitStack.pop();
            number2 = digitStack.pop();
            operator = operatorStack.pop();
            // 5.2 两个字符同级,若前一个字符为"-",则改当前字符为同级的另一字符
            if (!operatorStack.isEmpty()) {
                operator = ArrayStack2.changeOperator(operator, operatorStack.peekTop());
            }
            // 5.3 计算结果
            result = ArrayStack2.calculator(number1, number2, operator);
            // 5.4 结果入数字栈
            digitStack.push(result);
        }

        // 6. 返回数字栈剩余的那个数字
        return digitStack.pop();
    }

}

2. 栈(为计算器服务)

class ArrayStack2 {
    private int maxSize;
    private int[] array;
    private int top = -1;

    public ArrayStack2(int maxSize) {
        this.maxSize = maxSize;
        this.array = new int[maxSize];
    }

    public boolean isFull() {
        return this.top == this.maxSize - 1;
    }

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


    public void push(int data) {
        if (this.top == this.maxSize - 1) {
            throw new RuntimeException("full");
        }
        this.top++;
        this.array[top] = data;
    }

    public int pop() {
        if (this.top == -1) {
            throw new RuntimeException("empty");
        }
        int tempData = this.array[this.top];
        this.array[this.top] = 0;
        this.top--;
        return tempData;
    }

    public int getLength() {
        int count = 0;
        for (int i = this.top; i >= 0; i--) {
            count++;
        }
        return count;
    }

    public void displayAllDataFromTop() {
        if (this.top == -1) {
            throw new RuntimeException("empty");
        }
        for (int i = this.top; i >= 0; i--) {
            System.out.printf("array[%d] -> %d\n", i, this.array[i]);
        }
    }

    /**
     * 返回运算符的优先级
     *      * 和 / 是第一高,返回1
     *      + 和 - 是第二高,返回10
     *      非法字符,返回-1
     * @param operator - 输入的运算符
     * @return - 运算符优先级的数字级别
     */
    public static int operatorPriority(int operator) {
        if (operator == '*' || operator == '/') {
            return 1;
        } else if (operator == '+' || operator == '-') {
            return 0;
        } else {
            return -1;
        }
    }

    /**
     * 判断是否是运算符
     * @param operator - 要判断的运算符
     * @return - true合法,false非法
     */
    public static boolean isValidOperator(int operator) {
        return operator == '+' || operator == '-' || operator == '*' || operator == '/';
    }

    /**
     * 判断是否是数字
     * @param number - 要判断的运算符
     * @return - true合法,false非法
     */
    public static boolean isValidNumber(int number) {
        return number == '0'
                || number == '1'
                || number == '2'
                || number == '3'
                || number == '4'
                || number == '5'
                || number == '6'
                || number == '7'
                || number == '8'
                || number == '9';
    }

    /**
     * 通过所给的运算符,计算所给的两个数
     * @param num1
     * @param num2
     * @param operator
     * @return - 计算结果
     */
    public static int calculator(int num1, int num2, int operator) {
        int result = 0;
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num2 - num1;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                result = num2 / num1;
                break;
            default:
                break;
        }
        return result;
    }

    /**
     * 若前一个字符为"-",则改当前字符为同级的另一字符
     * @param currentOperator - 当前字符
     * @param preOperator - 前一个字符
     * @return - 返回更改后的字符
     */
    public static int changeOperator(int currentOperator, int preOperator) {
        if (preOperator == '-' && currentOperator == '-') {
            currentOperator = '+';
        } else if (preOperator == '-' && currentOperator == '+') {
            currentOperator = '-';
        }
        return currentOperator;
    }

    /**
     * 查看栈顶的值
     * @return - 栈顶值
     */
    public int peekTop() {
        return this.array[top];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
做一门精致,全面详细的 java数据结构与算法!!!让天下没有难学的数据结构,让天下没有难学的算法,不吹不黑,我们的讲师及其敬业,可以看到课程视频,课件,代码的录制撰写,都是在深夜,如此用心,其心可鉴,他不掉头发,谁掉头发???总之你知道的,不知道的,我们都讲,并且持续更新,走过路过,不要错过,不敢说是史上最全的课程,怕违反广告法,总而言之,言而总之,这门课你值得拥有,好吃不贵,对于你知识的渴求,我们管够管饱话不多说,牛不多吹,我们要讲的本门课程内容:稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、、前缀、中缀、后缀表达式中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值