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

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.mfbz.cn/a/49098.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MFC表格控件CListCtrl的改造及用法

1、目的 简单描述MFC的表格控件使用方法。Qt适用习惯了以后MFC用的比较别扭&#xff0c;因此记录一下以备后续复制代码使用。由于MFC原生的CListCtrl比较局限&#xff0c;比如无法改变表格的背景色、文字颜色等设定&#xff0c;因此先对CListCtrl类进行重写&#xff0c;以便满足…

Jenkins 拉取 GitHub 私有仓库失败问题

添加仓库的时候提示 stderr: fatal: Cannot prompt because user interactivity has been disabled. 把在 GitHub账户设置中生成的个人访问令牌填到地址里

第54步 深度学习图像识别:MLP-Mixer建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;MLP-Mixer MLP-Mixer&#xff08;Multilayer Perceptron Mixer&#xff09;是Google在2021年提出的一种新型的视觉模型结构。它的主要特点是完全使用多层感知机&#xff08;MLP&#xff09;来处理图像&#…

Docker Compose(九)

一、背景&#xff1a; 对于现代应用来说&#xff0c;大多数都是通过很多的微服务互相协同组成一个完整的应用。例如&#xff0c;订单管理、用户管理、品类管理、缓存服务、数据库服务等&#xff0c;他们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事…

Sentinel Dashboard集成Nacos

1.前言 当项目上Sentinel Dashboard做流量监控的时候&#xff0c;我们可以通过Sentinel控制台修改限流配置&#xff0c;但当我们使用Nacos作为配置中心动态配置流控规则的时候&#xff0c;问题就来了。 首先我们要明白&#xff0c;Sentinel Dashboard的配置是从机器的内存中加…

【kubernetes系列】flannel之vxlan模式原理

概述 在Kubernetes中要保证容器之间网络互通&#xff0c;网络至关重要。而Kubernetes本身并没有自己实现容器网络&#xff0c;而是而是借助CNI标准&#xff0c;通过插件化的方式自由接入进来。在容器网络接入进来需要满足如下基本原则&#xff1a; Pod无论运行在任何节点都可…

运算放大器--------加减运算电路

反向求和运算电路 电路 公式 同向加法运算电路 电路 公式 加减运算电路 分别求正向输入的输出和反相输入的输出&#xff0c;然后求和就可以得到到最终的输出。 切记&#xff0c;虚短虚断不是真正的断路和短路。

this关键字和同步异步宏认为微任务理解

目录 js面试常见问题&#xff1a;1.this指向 2.闭包定义和作用 3.原型链 4.异步协程 this关键字 this主要有以下几个使用场合。 1&#xff09;全局环境 &#xff08;2&#xff09;构造函数 &#xff08;3&#xff09;对象的方法 避免多层this 避免数组处理方法中的 this 避免回…

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…

lc154.寻找旋转排序数组中的最小值

最小元素的位置以旋转次数为索引的位置&#xff0c;但是没有告诉旋转次数&#xff0c;换一种思路 当遇到arr[index] > arr[index1]时&#xff0c;index1为最小元素的位置。首位位置独立比较。但是这种方法还是遍历数组 观察两组数的中间值与首尾的值&#xff0c;又由于数组…

【C++】图

目录 图的存储结构邻接矩阵&#xff08;Adjacency Matrix&#xff09;无向(网)图邻接矩阵代码实现&#xff1a; 邻接表(Adjacency Lists) 图的遍历邻接矩阵深度和广度遍历DFS_BFS邻接表深度和广度遍历DFS_BFS 最小生成树普里姆&#xff08;Prim&#xff09;算法克鲁斯卡尔&…

Spring 6【单例设计模式、bean标签的scope属性、Spring 循环注入问题】(八)-全面详解(学习总结---从入门到深化)

目录 十五、单例设计模式 十六、bean标签的scope属性 十七、Spring 循环注入问题 十五、单例设计模式 设计模式&#xff1a;根据面向对象五大设计思想衍生出的23种常见代码写法&#xff0c;每种写法可以专门解决一类问题。 单例设计模式&#xff1a;保证某个类在整个应用程…

PLC的高端版本通常具有以下特点:

高速处理能力&#xff1a;高端PLC通常具有更快的处理速度和更高的运行频率&#xff0c;可以处理更复杂的控制逻辑和更多的输入/输出信号。 大容量存储&#xff1a;高端PLC通常具有更大的存储容量&#xff0c;可以保存更多的程序和数据&#xff0c;以满足更复杂的应用需求。 多种…

uniapp 选择城市定位 根据城市首字母分类排序

获取城市首字母排序&#xff0c;按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…

基于SSM实现个人随笔分享平台:创作心灵,分享自我

项目简介 本文将对项目的功能及部分细节的实现进行介绍。个人随笔分享平台基于 SpringBoot SpringMVC MyBatis 实现。实现了用户的注册与登录、随笔主页、文章查询、个人随笔展示、个人随笔查询、写随笔、草稿箱、随笔修改、随笔删除、访问量及阅读量统计等功能。该项目登录模…

【C语言day08】

int n5; int a[n][n2] 数组定义下角标不能为变量 注&#xff1a;C99标准中支持了使用变量本题考查的是二维数组的元素访问&#xff0c;A选项是 正确的&#xff0c;X[i]就是第i行的数组名&#xff0c;数组名表示首元素的地址&#xff0c;X[i]表示第i行的第一个元素的地址&#…

Qgis二次开发-QgsMapLayer(加载矢量、栅格图层)

1.简介 QgsMapLayer是所有地图层类型的基类&#xff0c;这是所有地图层类型(矢量&#xff0c;栅格)的基类&#xff0c;首先定义一个QgsMapCanvas地图画布&#xff0c;然后画布上添加图层&#xff0c;使用以下方法设置图层集合。 //设置当前图层集合 void setLayers (const QL…

【c语言进阶】字符函数和字符串函数知识总结

字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strnca…

【Qt】QML-02:QQuickView用法

1、先看demo QtCreator自动生成的工程是使用QQmlApplicationEngine来加载qml文件&#xff0c;下面的demo将使用QQuickView来加载qml文件 #include <QGuiApplication> #include <QtQuick/QQuickView>int main(int argc, char *argv[]) {QGuiApplication app(argc,…

electron dialog.showMessageBox使用案例

electron 版本&#xff1a;25.3.1 index.html <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>Hello World!</title><meta http-equiv"Content-Security-Policy" content"script-src self unsa…
最新文章