[jdk17] 使用栈结构对计算器的一个简单实现

本文介绍了一个使用Java编写的程序,通过栈数据结构来解析和计算整数算术表达式,包括运算符优先级判断和运算过程的实现。
摘要由CSDN通过智能技术生成

完整代码:

package LinkList.Stack.CalculateString;

import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.Stack;

public class CaculateStringTest {

    Stack<Integer> number = new Stack<>();
    Stack<Character> operator = new Stack<>();

    /**
     * 计算运算符优先级
     * @param operator
     * @return 0代表优先级低,1代表优先级相等,2代表优先级高
     */
    public int isPriority(char operator){
        char prev = this.operator.peek();
        if (prev == '+' || prev == '-'){
            if (operator == '*' || operator == '/'){
                return 2;
            }else return 1;
        }else if (prev == '*' || prev == '/'){
            if (operator == '+' || operator == '-'){
                return 0;
            }else return 1;
        }
        throw new RuntimeException("未知错误");
    }

    /**
     * 运算并返回计算结果(默认后一个数与前一个数运算)
     * @param num1
     * @param num2
     * @param operator
     * @return
     */
    public int calculate(int num1,int num2,char operator) throws ArithmeticException{
        switch (operator){
            case '+'-> {
                return num2+num1;
            }
            case '-'->{
                return num2-num1;
            }
            case '*'->{
                return num2*num1;
            }
            case '/'->{
                return num2/num1;
            }
        }
        throw new RuntimeException("未知错误");
    }

    public static void main(String[] args) {
        CaculateStringTest caculateStringTest = new CaculateStringTest();
        boolean isLoop = true;
        Scanner scan = new Scanner(System.in);
        while (isLoop){
            System.out.println("-----------------------------------------------------------------------------------");
            System.out.println("输入1,计算算式");
            System.out.println("输入0,退出程序");
            System.out.println("-----------------------------------------------------------------------------------");
            String str = scan.next();
            switch (str){
                case "1" ->{
                    System.out.println("请输入算式(仅能计算整数,要求除法能整除):");
                    String word = scan.next();
                    long startTime = System.currentTimeMillis();
                    if (word.matches("^[^-+*/0-9]+$")){
                        //匹配到非法字符
                        System.out.println("请输入正确的表达式!");
                        continue;
                    }
                    char[] calculation = word.toCharArray();
                    //numStr 用于拼接多位数,当遍历到符号时再重置
                    String numStr = "";
                    for (int i = 0; i < calculation.length; i++) {
                        //如果是数字,直接入数栈
                        if (calculation[i] >= '0' && calculation[i] <= '9') {
                            //处理多位数
                            numStr += calculation[i];
                            //遍历到最后一个数字时,记得把最后一个数也压入数栈
                            if (i == calculation.length - 1) caculateStringTest.number.push(Integer.parseInt(numStr));

                        }else if(calculation[i] == '+' || calculation[i] == '-' || calculation[i] == '*' || calculation[i] == '/'){
                            //如果是运算符,符号栈若没元素直接入栈
                            //如果当前符号优先级小于等于符号栈中元素,先计算后将当前符号入栈
                            //如果当前符号优先级大于符号栈中元素,如果此时符号栈顶元素是'-',则需要反转符号栈顶元素且数栈中的栈顶元素符号修改为符号栈的栈顶元素
                            //如果此时符号栈顶元素是'+',则不需要反转符号栈顶元素且数栈需带符号,最后将当前符号放入符号栈栈顶

                            //将拼接好的numStr转成整数后压入数栈
                            caculateStringTest.number.push(Integer.parseInt(numStr));
                            //重置numStr
                            numStr = "";

                            //符号栈为空,直接将符号入符号栈
                            if (caculateStringTest.operator.isEmpty()){
                                caculateStringTest.operator.push(calculation[i]);
                            }else if (caculateStringTest.isPriority(calculation[i]) != 2){
                                //跟上一个运算符相比,当前运算符优先级低或者相等
                                //数栈弹出两个元素,符号栈弹出一个元素,计算后的结果压入数栈
                                try {
                                    caculateStringTest.number.push(caculateStringTest.calculate(caculateStringTest.number.pop(),caculateStringTest.number.pop(),caculateStringTest.operator.pop()));
                                }catch (ArithmeticException e){
                                    System.out.println("出现算数异常!程序退出.");
                                    return;
                                }

                                //将当前符号压入符号栈
                                caculateStringTest.operator.push(calculation[i]);
                            } else if (caculateStringTest.isPriority(calculation[i]) == 2) {
                                //跟上一个运算符相比,当前运算符优先级高

                                //当上一个运算符是'-'
                                if (caculateStringTest.operator.peek() == '-'){
                                    //先将符号栈弹出,然后反转成'+'压入符号栈
                                    caculateStringTest.operator.pop();
                                    caculateStringTest.operator.push('+');

                                    //将数栈弹出,将弹出的数乘以-1处理后压回数栈
                                    int pop = caculateStringTest.number.pop();
                                    caculateStringTest.number.push((-1 * pop));
                                }
                                caculateStringTest.operator.push(calculation[i]);
                            }
                        }
                    }
                    //遍历完算式,计算数栈和符号栈剩下的运算
                    while (!caculateStringTest.operator.isEmpty()){
                        try {
                            caculateStringTest.number.push(caculateStringTest.calculate(caculateStringTest.number.pop(), caculateStringTest.number.pop(), caculateStringTest.operator.pop()));
                        }catch (ArithmeticException e){
                            System.out.println("出现算术异常!程序退出.");
                            return;
                        }
                    }
                    int result = caculateStringTest.number.pop();
                    System.out.printf("该计算结果为:[%d]",result);
                    long endTime = System.currentTimeMillis();

                    System.out.println();
                    System.out.println("计算花费时间: " + (endTime - startTime) + " ms");
                }
                case "0"-> isLoop = false;
            }

        }



    }


}

测试图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值