博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 栈 Stack类 栈的应用--中缀表达式转后缀表达式并计算
阅读量:5796 次
发布时间:2019-06-18

本文共 4902 字,大约阅读时间需要 16 分钟。

  hot3.png

package com.test;import java.math.BigDecimal;import java.util.Stack;/** * 利用栈实现中缀表达式转后缀表达式,并提供对后缀表达式的计算 * Created by jockiller on 2016/3/4. */public class BiaoDaShi {    public static void main(String[] args) {        String bds = "60/(5-2) + 5 *(20 *(3-1))";        System.out.println(bds);        String hzBds = revertBds(bds);        System.out.println(hzBds);        BigDecimal res = calculate(hzBds);        System.out.println(res);    }    /**     * 对后缀表达式进行计算     * @param hzBds     * @return     */    private static BigDecimal calculate(String hzBds) {        Stack
stack = new Stack<>(); String[] split = hzBds.split(" "); for (String s : split) { if (null == s || "".equals(s.trim())) continue; if (YunSuanFu.isYunSuanFu(s.charAt(0))){ //如果是运算符 则将堆中的两个值拿出来计算 然后放回堆中 stack.push(stackoperate(stack.pop(),stack.pop(),s.charAt(0))); }else { stack.push(new BigDecimal(s)); } } return stack.pop(); } /** * 根据运算符进行计算 * @param v1 * @param v2 * @param c * @return */ private static BigDecimal stackoperate(BigDecimal v2, BigDecimal v1, char c) { YunSuanFu yun = YunSuanFu.parse(c); switch (yun){ case MULTIPLY: return v2.multiply(v1); case DIVIDE: return v1.divide(v2); case ADD: return v1.add(v2); case MINUS: return v1.subtract(v2); default: throw new RuntimeException("不支持的运算"); } } /** * 中缀表达式转换为后缀表达式 * * @param bds 中缀表达式 * @return */ private static String revertBds(String bds) { Stack
stack = new Stack(); String s = bds.replaceAll(" ", ""); StringBuffer sb = new StringBuffer(); boolean nextPop = false; char ic; for (int i = 0; i < s.length(); i++) { if (YunSuanFu.isYunSuanFu(ic = s.charAt(i))) { if (nextPop) { nextPop = false; sb.append(" ").append(stack.pop()); sb.append(" ").append(stack.pop()); } //判断当前运算符是否是右括号 if (ic == YunSuanFu.RIGHT.ele) { //将栈中上一个左括号之前的运算符出栈 while (true) { if ((ic = stack.pop()) != YunSuanFu.LEFT.ele) { sb.append(" ").append(ic); } else { // 如果左括号之前的一个运算符是或者除 那么也需要出栈 if (stack.peek() == YunSuanFu.DIVIDE.ele || stack.peek() == YunSuanFu.MINUS.ele) { sb.append(" ").append(stack.pop()); } break; } } } else if (stack.size() > 1 && YunSuanFu.isPriorityHigh(ic, stack.peek())) { //判断当前栈中是否有一个运算符 并且新运算符的优先级高于当前优先级,如果是 则下一位的数字输出 并将栈中的两个运算符出栈 nextPop = true; stack.push(ic); sb.append(" "); } else { //如果是运算符 则入栈 stack.push(ic); sb.append(" "); } } else { sb.append(ic); } if (i == s.length() - 1) { int size = stack.size(); for (int j = 0; j < size; j++) { sb.append(" ").append(stack.pop()); } } } return sb.toString(); } private enum YunSuanFu { ADD('+'), MINUS('-'), MULTIPLY('*'), DIVIDE('/'), LEFT('('), RIGHT(')'),; private char ele; YunSuanFu(char ele) { this.ele = ele; } /** * 判断是不是运算符 * * @param c * @return */ public static boolean isYunSuanFu(char c) { for (YunSuanFu fu : YunSuanFu.values()) { if (fu.ele == c) { return true; } } return false; } /** * 转换运算符 * * @param c * @return */ public static YunSuanFu parse(char c) { for (YunSuanFu fu : YunSuanFu.values()) { if (fu.ele == c) { return fu; } } throw new RuntimeException("未知运算符"); } /** * 判断第一个运算符优先级是否高于第二个 * * @param c1 * @param c2 * @return */ public static boolean isPriorityHigh(char c1, char c2) { if ((c1 == MULTIPLY.ele || c1 == DIVIDE.ele) && (c2 == ADD.ele || c2 == MINUS.ele)) { return true; } return false; } }}

转载于:https://my.oschina.net/razox/blog/851802

你可能感兴趣的文章
通过容器编排和服务网格来改进Java微服务的可测性
查看>>
re:Invent解读:没想到你是这样的AWS
查看>>
[翻译]AKKA笔记 -ACTOR SUPERVISION - 8
查看>>
Meteor:添加用户系统
查看>>
当我们谈网络时,我们谈些什么(5)链路层概述
查看>>
PyTips 0x02 - Python 中的函数式编程
查看>>
从MongoDB2.4升级到3.0的详细步骤
查看>>
阿里云安全肖力:安全基础建设是企业数字化转型的基石 ...
查看>>
STM32学习笔记(三)——外部中断的使用
查看>>
使用《Deep Image Prior》来做图像复原
查看>>
如何用纯 CSS 为母亲节创作一颗像素画风格的爱心
查看>>
Linux基础命令---rmdir
查看>>
阿里云胡晓明:未来将探索区块链在工业互联网领域的应用
查看>>
Java Memento Pattern(备忘录模式)
查看>>
优秀程序员共有的7种优秀编程习惯
查看>>
iOS sqlite3(数据库)
查看>>
粤出"飞龙",打造新制造广东样本
查看>>
编玩边学获数千万元A轮融资,投资方为君联资本
查看>>
maven常用命令
查看>>
开发者论坛一周精粹(第五十五期) 全站HTTPS之OSS教程 一次可以备案几个网站?...
查看>>