中缀表达式转后缀表达式,使用逆波兰计算。可以计算小数

news2024/12/23 22:18:55

1、使用方法

传递一个分开保存符号与数字的List即可:List SumNumber;

获取参数的构造方法如下:

    public ReversePolish(List<String> sumNumber) {
        SumNumber = sumNumber;
    }

要求的List保存数据的方式如下:
例如:1+2+3
在这里插入图片描述
然后使用 EvaluatePostfixExpressions方法传递出一个保存好结果的String。

2、代码实现

package com.example.computermoblie;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Stack;

public class ReversePolish {
    public List<String> SumNumber;


    Stack<BigDecimal> SymbolStack = new Stack<>();

    //表示没有计算错误的情况
    private boolean Error = false;

    public static final int LeftBrack = 0;   //左括号优先级
    public static final int AandS = 1;   //加减法
    public static final int MandD = 2;   //乘除
    public static final int RightBrack = 3;   //右括号优先级

    //中缀转后缀
    public Queue<String> InfixToSuffix() {
        Queue<String> queue = new ArrayDeque<>();
        Stack<String> swapStack = new Stack<>();

        for (int i = 0; i < SumNumber.size(); i++) {
            String isStr = SumNumber.get(i);

            if (!IsSymbol(isStr)) {
                queue.add(isStr); // 将数字直接添加到输出队列中
            } else {
                if (swapStack.isEmpty() || isStr.equals("(")) {
                    swapStack.push(isStr);
                } else if (isStr.equals(")")) {
                    if(!swapStack.isEmpty()){
                        while (!swapStack.peek().equals("(")) {
                            queue.add(swapStack.pop());
                        }
                        swapStack.pop(); // 弹出 "("
                    }
                } else {
                    while (!swapStack.isEmpty() && JudgmentPriority(swapStack.peek(), isStr)) {
                        queue.add(swapStack.pop());
                    }
                    swapStack.push(isStr);
                }
            }
        }

        while (!swapStack.isEmpty()) {
            queue.add(swapStack.pop());
        }

        return queue;
    }

    public String EvaluatePostfixExpressions() {
        Error = false;  // 表示运算未发现错误
        BigDecimal ret = null; // 表示最后的运算结果
        Queue<String> queue = InfixToSuffix();  // 获取后缀表达式

        Log.d("WQWQ",queue.toString());

        while (!queue.isEmpty()) {
            String str = queue.remove();

            if (!IsSymbol(str)) {
                //保存数据
                try {
                    BigDecimal number = new BigDecimal(str);
                    SymbolStack.push(number);
                } catch (NumberFormatException e) {
                    Log.d("Number","出现空值");
                }
            } else {
                if (SymbolStack.size() < 2) {
                    Error = true; // 栈中元素不足2个,运算错误
                    break;
                }

                BigDecimal op2 = SymbolStack.pop();
                BigDecimal op1 = SymbolStack.pop();
                BigDecimal result = null;

                switch (str) {
                    case "+":
                        result = op1.add(op2);
                        break;
                    case "-":
                        result = op1.subtract(op2);
                        break;
                    case "×":
                        result = op1.multiply(op2);
                        break;
                    case "÷":
                        if (op2.compareTo(BigDecimal.ZERO) == 0) {
                            Error = true; // 除数为零,运算错误
                            break;
                        }
                        result = op1.divide(op2, 3, RoundingMode.HALF_UP);
                        break;
                    default:
                        Error = true; // 非法的运算符,运算错误
                        break;
                }

                if (Error) {
                    break;
                } else {
                    SymbolStack.push(result);
                }
            }
        }

        if (Error) {
            return "Error"; // 出现错误后直接返回错误信息
        } else {
            if (!SymbolStack.isEmpty()) {
                ret = SymbolStack.pop();
            }
            // 使用toEngineeringString()方法将结果输出为工程计数法
            return ret.toEngineeringString();
        }
    }

    public ReversePolish(List<String> sumNumber) {
        SumNumber = sumNumber;
    }

    //判断是否为符号
    public boolean IsSymbol(String str) {
        boolean isSymbole = false;
        if (str.equals("+")) {
            isSymbole = true;
        } else if (str.equals("-")) {
            isSymbole = true;
        } else if (str.equals("×")) {
            isSymbole = true;
        } else if (str.equals("÷")) {
            isSymbole = true;
        } else if (str.equals("(")) {
            isSymbole = true;
        } else if (str.equals(")")) {
            isSymbole = true;
        }

        return isSymbole;
    }

    //判断优先级
    public boolean JudgmentPriority(String PreantStr, String SunStr) {
        //默认PreantStr优先级小于SunStr
        boolean value = false;

        if (SymbolValue(PreantStr) >= SymbolValue(SunStr)) {
            value = true;
        }

        return value;
    }

    //判断属于什么符号
    public int SymbolValue(String str) {
        int Value = LeftBrack;

        if (str.equals("+")) {
            Value = AandS;
        } else if (str.equals("-")) {
            Value = AandS;
        } else if (str.equals("×")) {
            Value = MandD;
        } else if (str.equals("÷")) {
            Value = MandD;
        } else if (str.equals("(")) {
            Value = LeftBrack;
        } else if (str.equals(")")) {
            Value = RightBrack;
        }
        return Value;
    }

    public List<String> getSumNumber() {
        return SumNumber;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/791094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】详解多态的底层原理

文章目录 前言1. 虚函数表指针与虚函数表2. 子类的虚函数表&#xff08;单继承&#xff09;3. 多态的实现原理3.1 多态是如何实现的3.2 多态调用与非多态调用的区别3.3 为什么父类的对象不能实现多态 4. 其它多态相关问题的理解4.1 虚函数是存在哪里的&#xff1f;4.2 子类新增…

手机照片误删除?无需担忧,点击这里,即可轻松恢复

手机照片误删除&#xff1f;无需担忧&#xff0c;点击这里&#xff0c;即可轻松恢复 开头&#xff1a;在数字化时代&#xff0c;手机已成为我们生活中不可或缺的伙伴。随着手机摄影的普及&#xff0c;我们记录了许多珍贵的瞬间和回忆。然而&#xff0c;有时候我们不小心误删除…

项目经理必备的5种管理能力

作为中层管理者&#xff0c;需要同时完成上级的任务安排和照顾下属的情绪&#xff0c;这是职场中最具挑战性的管理能力。项目经理必备能力中&#xff0c;计划制定、有效授权、高效沟通、化解冲突、项目跟踪是至关重要的。 1、计划制定是项目管理的关键。 作为项目经理&#…

Tribon二次开发- tbbatchjob

在Tribon安装目录下C:\Tribon\M3\Bin里面有许多未知用途的exe,有的双击后时一个DOS终端,有的一闪而过,有的需要按照提示输入信息,有的需要提前在指定的目录配置文件,该如何使用呢? 这些exe大多可以在Tribon以外通过.NET来使用,有的可以通过添加.NET项目引用来使用,有的…

聊聊spring中bean的作用域

前言 今天分享一下spring bean的作用域&#xff0c;理解bean的作用域能够在使用过程中避免一些问题&#xff0c;bean的作用域也是spring bean创建过程中一个重要的点。 Spring bean的作用域类型 singleton&#xff08;单例模式&#xff09;&#xff1a;在整个应用程序的生命周…

成都爱尔蔡裕:泡在“糖”里的脆弱血管,暴露在眼睛深处

糖尿病是一组由多病因引起的以慢性高血糖为特征的终身性代谢性疾病。长期血糖增高&#xff0c;大血管、微血管受损并危及心、脑、肾、周围神经、眼睛、足等。医生临床数据显示&#xff0c;糖尿病发病后10年左右&#xff0c;将有30%&#xff5e;40%的患者至少会发生一种并发症&a…

【TypeScript】对函数类型的约束定义

导读 函数是JavaScript 中的 一等公民 概念&#xff1a;函数类型的概念是指给函数添加类型注解&#xff0c;本质上就是给函数的参数和返回值添加类型约束 文章目录 声明式函数:表达式函数&#xff1a;箭头函数可选参数和默认参数&#xff1a;参数默认值&#xff1a;过剩参数的处…

脚本 打开 cmd 跳转到某个文件夹并执行某些命令

很多时候我们需要启动windows安装的redis、nacos等。 通常我们可以打开安装软件的目录&#xff0c;在文件夹目录那一栏输入cmd,再执行相关启动命令但是这样比较麻烦&#xff0c;现在我们写一个bat脚本&#xff0c;直接启动脚本就可以实现启动程序了。 例如&#xff0c; 1&…

docker入门讲解

目录 第 1 章 Docker核心概念与安装 为什么使用容器&#xff1f; Docker是什么 Docker设计目标 Docker基本组成 容器 vs 虚拟机 Docker应用场景 Linux 安装 Docker 第 2 章 Docker镜像管理 Docker 容器管理 Docker 容器数据持久化 Docker 容器网络 Dockerfile 定制…

JAVA的数据类型与变量

目录 1. 字面常量 2. 数据类型 3. 变量 3.2 长整型变量 3.3 短整型变量 3.4 字节型变量 3.5双精度浮点型 3.6 单精度浮点型 3.7字符型变量 3.8布尔型变量 4.类型转换 4.1自动类型转换(隐式) 4.2强制类型转换(显式) 5.字符串类型 1. 字面常量 字面常量的分类&am…

深度学习之梯度下降算法

0.1 学习视频源于&#xff1a;b站&#xff1a;刘二大人《PyTorch深度学习实践》 0.2 本章内容为自主学习总结内容&#xff0c;若有错误欢迎指正&#xff01; 1 线性模型 1.1 通过简单的线性模型来举例&#xff1a; 1.2 如图&#xff0c;简单的一个权重的线性模型&#xff0c…

透明屏的应用范围广吗?

透明屏是一种新型的显示技术&#xff0c;它可以使屏幕显示的内容透明&#xff0c;让用户可以同时看到屏幕上的图像和背后的物体。 透明屏的应用领域非常广泛&#xff0c;可以用于商业广告、展览展示、智能家居等多个领域。 透明屏的原理是利用透明材料和光学技术&#xff0c;…

通过el-tab切换Echarts图表显示不全问题

一、背景 在让日常开发中很多时候会通过el-tab选项卡方式去分类统计数据&#xff0c;本文我们主要是针对统计中用到了echarts图表&#xff0c;在刚接触时可能会遇到默认选项卡可以正常显示图表数据&#xff0c;但是切换选项卡以后会出现图表大小出现问题&#xff0c;当然原因就…

第2集丨webpack 江湖 —— 创建一个简单的webpack工程demo

目录 一、创建webpack工程1.1 新建 webpack工程目录1.2 项目初始化1.3 新建src目录和文件1.4 安装jQuery1.5 安装webpack1.6 配置webpack1.6.1 创建配置文件&#xff1a;webpack.config.js1.6.2 配置dev脚本1.7 运行dev脚本 1.8 查看效果1.9 附件1.9.1 package.json1.9.2 webpa…

MyBatisPlus之DML编程控制

MyBatisPlus之DML编程控制 1. id生成策略控制&#xff08;Insert&#xff09;1.1 id生成策略控制&#xff08;TableId注解&#xff09;1.2 全局策略配置id生成策略全局配置表名前缀全局配置 2. 多记录操作&#xff08;批量Delete/Select&#xff09;2.1 按照主键删除多条记录2.…

【java实习评审】对小说更新时间点的并发压力的短链接接口实现比较到位

大家好&#xff0c;本篇文章分享一下【校招VIP】免费商业项目“推推”第一期书籍详情模块java同学的代码周最佳作品。该同学来自西安邮电大学通信工程专业。本项目亮点难点&#xff1a;1 热门书籍在更新点的访问压力&#xff0c;2 书籍更新通知的及时性和有效性&#xff0c;3 书…

GlobalProtect-点击连接按钮无响应

GlobalProtect-点击连接按钮无响应 解决方案 重启PanGPS服务 点击连接

C++输入字符串函数cin.getline()

1.函数作用 接受一个字符串&#xff0c;可以接收空格并输出。 2.函数的完整形式 cin.getline(字符数组名,字符个数,结束标志) 第三个参数可以省略&#xff0c;当第三个参数省略之后&#xff0c;系统默认为’\0’。 若指定参数“字符个数”为n&#xff0c;则利用cout函数输出…

LiveGBS流媒体平台GB/T28181常见问题-TOKEN有效期是多久如何设置token有效期StreamToken和URLToken

LiveGBS中TOKEN有效期是多久如何设置token有效期StreamToken和URLToken 1、获取TOKEN2、TOKEN有效期3、默认token有效期3、自定义token加密key3.1、token_key3.2、stream_token_key 4、如何配置一直有效的token4.1、URLToken4.2、StreamToken 5、动态有效期6、流地址鉴权开启后…