中缀表达式的计算的java实现(使用栈(双栈)实现)

22 篇文章 0 订阅

工具类(包含实现方法)

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Stack;

/**
 * className:Util
 *
 * @author:zjl
 * @version:0.1
 * @date:2020/8/121:36
 * @since:jdk1.8
 */
public class Util {

    /**
     * 实现方法
     *
     * @param s
     * @return
     */
    public static Double calculateString(String s) {

        //字符串转为字符数组
        char[] chars = s.toCharArray();
        Stack<Double> stackNum = new Stack<>();
        Stack<Character> stackSym = new Stack<>();
        HashMap<Character, Integer> priority = new HashMap<>();
        //定义运算符优先级
        priority.put('+', 0);
        priority.put('-', 0);
        priority.put('*', 1);
        priority.put('/', 1);
        priority.put('(', -1);
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (!Character.isDigit(c) && c != '.') {//非数字
                if (stackSym.empty()) {//符号栈为空直接进栈
                    stackSym.push(c);
                } else {
                    if (c == '(') {//直接进栈
                        stackSym.push(c);
                    } else if (c == ')') {
                        while (stackSym.peek() != '(') {//依次出栈进行运算直到栈顶运算符为"("
                            calculateOne(stackNum, stackSym);
                        }
                        stackSym.pop();
                    } else {
                        if (priority.get(c) > priority.get(stackSym.peek())) {//当前运算符优先级大于符号栈栈顶运算符优先级直接进栈
                            stackSym.push(c);
                        } else {//当前运算符优先级小于符号栈栈顶运算符优先级,依次出栈进行运算,直到当前运算符优先级大于符号栈栈顶运算符优先级
                            while (priority.get(c) <= priority.get(stackSym.peek())) {
                                calculateOne(stackNum, stackSym);
                                if (stackSym.empty())
                                    break;
                            }
                            stackSym.push(c);
                        }
                    }

                }
            } else {//数字直接进入数栈
                StringBuilder sb = new StringBuilder();
                char ch = c;
                while (Character.isDigit(ch) || c == '.') {//处理多位数(拼接)
                    sb.append(ch);
                    if (i == chars.length - 1 || (!Character.isDigit(chars[i + 1]) && chars[i + 1] != '.'))
                        break;
                    i++;
                    ch = chars[i];
                }
                stackNum.push(Double.valueOf(String.valueOf(sb + "")));
            }

        }
        while (!stackSym.empty()) {//字符数组进栈完毕,依次出栈进行运算,直到符号栈为空
            calculateOne(stackNum, stackSym);
        }
        return stackNum.pop();//运算结果为数栈的仅有的一个元素,返回
    }

    /**
     * 数栈出栈两个数,符号栈出栈一个符号 进行计算 并将结果存进数栈
     *
     * @param stackNum
     * @param stackSym
     */
    public static void calculateOne(Stack<Double> stackNum, Stack<Character> stackSym) {
        Character operator = stackSym.pop();
        Double num1 = stackNum.pop();
        Double num2 = stackNum.pop();
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        switch (operator) {
            case '*':
                double result = b2.multiply(b1).doubleValue();
                stackNum.push(result);
                break;
            case '/':
                double result1 = b2.divide(b1).doubleValue();
                stackNum.push(result1);
                break;
            case '+':
                double result2 = b2.add(b1).doubleValue();
                stackNum.push(result2);
                break;
            case '-':
                double result3 = b2.subtract(b1).doubleValue();
                stackNum.push(result3);
                break;
        }
    }

}

测试类

/**
 * className:Test
 *
 * @author:zjl
 * @version:0.1
 * @date:2020/8/217:49
 * @since:jdk1.8
 */
public class Test {
    public static void main(String[] args) {
        Double result = Util.calculateString("(8*9-100/10*7)*22");
        System.out.println("(8*9-100/10*7)*22 = " + result);
        Double result0 = Util.calculateString("5*2*9/3+10-3");
        System.out.println("5*2*9/3+10-3 = " + result0);
        Double result1 = Util.calculateString("9/2/2*3-1");
        System.out.println("9/2/2*3-1 = " + result1);
        Double result2 = Util.calculateString("1000/5*3*(1+3)");
        System.out.println("1000/5*3*(1+3) = " + result2);
    }

}

测试结果
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值