java计算器,输入公式和对应变量的值
- 目标:最近想写个东西,本质就是一个计算器,我们可以输入公式(例如:a+b),然后把公式的值(a:10,b:20)也输入进去。最后得到结果。
- 核心:这个想法核心部分就是给一个公式,然后计算其结果。这个在网上有很多。比如我就参考的这个大佬的。附链接。
- 其核心思想就是用两个栈,一次记录操作数,一个值。链接中的方案数已经在字符串中了。
- 然后需要找到这个数。我想要的是数在一个map中,直接get出来就好了。
- 此外,计算过程中需要对减号特殊处理,因为这个减号可能表示这个数是要取反的。代码中我直接在数栈和运算符栈中分别加入了-1和乘号实现的。
java核心代码
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Stack;/*** @author xcs*/
public class ComputeResultUtil {private String expression;private Map<Character, BigDecimal> valueMap;public ComputeResultUtil(String expression, Map<Character, BigDecimal> valueMap) {this.expression = expression;this.valueMap = valueMap;}public BigDecimal compute() {Stack<BigDecimal> nums = new Stack<>();Stack<Character> ops = new Stack<>();//记录是否需要把 - 作为 负数存储boolean isOperatorPre = false;for (int i = 0; i < expression.length(); i++) {char c = expression.charAt(i);if (Character.isAlphabetic(c)) {isOperatorPre = false;nums.push(valueMap.get(c));} else if (c == '(') {isOperatorPre = true;ops.push(c);} else if (c == ')') {// 计算括号中的内容,直到遇到左括号while (ops.peek() != '(') {isOperatorPre = false;nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}// 有括号也出栈ops.pop();} else if (isOperator(c)) {if (c == '-' && (isOperatorPre || ops.empty())) {nums.push(new BigDecimal("-1"));ops.push('*');isOperatorPre = false;} else {while (!ops.empty() && needCalculatePre(c, ops.peek())) {nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}isOperatorPre = true;ops.push(c);}}}while (!ops.empty()) {nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}return nums.pop();}private static boolean isOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/';}private static boolean needCalculatePre(char op1, char op2) {if (op2 == '(' || op2 == ')') {return false;}return (op2 == '*' || op2 == '/') && (op1 == '+' || op1 == '-') || (op2 == '+' || op2 == '-') && (op1 == '+' || op1 == '-');}private static BigDecimal calculateByOps(char op, BigDecimal b, BigDecimal a) {switch (op) {case '+':return a.add(b);case '-':return a.subtract(b);case '*':return a.multiply(b).setScale(4, BigDecimal.ROUND_HALF_UP);case '/':if (b.compareTo(BigDecimal.ZERO) == 0) {throw new UnsupportedOperationException("Cannot divide by zero");}return a.divide(b, 4, RoundingMode.HALF_UP);default:throw new UnsupportedOperationException("Unknown operator " + op);}}
}
使用方代码
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;/*** @author xcs*/
public class ComputeResultMain {public static void main(String[] args) {System.out.print("输入公式(公式中的变量目前只支持单字符):");Scanner sc = new Scanner(System.in);String formula = sc.nextLine();System.out.println("输入公式中的变量值(例如:a:123,空行表示结束):");Map<Character, BigDecimal> valueMap = new HashMap<>();while (true) {String value = sc.nextLine();if (value.trim().isEmpty()) {break; // 空行作为结束标志}String[] split = value.split("[::]");valueMap.put(split[0].charAt(0), new BigDecimal(split[1]));}ComputeResultUtil computeResult = new ComputeResultUtil(formula, valueMap);System.out.println("计算结果为:" + computeResult.compute());}
}
- 收获:
- 首先就是这个计算的过程,上学的时候应该是学过的,但是基本都忘了,也是实在懒得写,就直接百度了,再次看下也算是学习了。
- 其次我也是第一次知道string.split(“[::]”)的写法,其含义是中文冒号和英文冒号拆分字符串。这种写法由于中括号中两个冒号中间没有拆分,所以适用于单字符。如果是多字符的,可以这样写.split(“字符1|字符2…”),例如"1###2##3".split(“###|##”),拆分结果是1,2,3。需要注意的是,其实现步骤可以理解为依次进行了两次拆分,但是拆分结果放在一个数组中。可以看下面两个图,一个"1###2##3".split(“###|##”),一个是"1###2##3".split(“##|###”),后者出现了#2的数据,这是因为后者先使用##进行拆分。


相关文章:
java计算器,输入公式和对应变量的值
目标:最近想写个东西,本质就是一个计算器,我们可以输入公式(例如:ab),然后把公式的值(a:10,b:20)也输入进去。最后得到结果。核心:这个想法核心部分就是给一个…...
加密货币赋能跨境电商:PayPal供应链金融服务如何引领行业新趋势
跨境电商行业近年来呈现出爆发式增长,随着全球化贸易壁垒的降低和数字经济的快速发展,越来越多的商家和消费者跨越国界进行交易。根据eMarketer的数据,全球跨境电商交易额在2023年已超过4万亿美元,并预计在未来几年内仍将保持两位…...
redis面试(二)List链表数据
list 列表 我们总是说List为列表,其实在真正的数据结构来说,redis是自己基于c语言来实现的双向链表数据结构,主要的逻辑就是每个节点都可以指向下一个节点,这个结构就属于链表数组结构。 每个节点中的属性如下: type…...
SpringDataJPA(三):多表操作,复杂查询
一、Specifications动态查询 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。 import …...
嵌入式硬件面试题集萃:从基础到进阶
基础问题 问题: 解释什么是微控制器,以及它与微处理器的区别。 答案: 微控制器是具有集成内存和输入/输出外设的微型计算机。与通用微处理器相比,微控制器通常用于控制特定应用,而不是执行通用计算任务。 问题: 什么是数字逻辑门,…...
easyui-datebox 只显示月份选择,默认开启月份,隐藏日期选择框
如果你使用 easyui-datebox 并希望隐藏日期选择框,只显示月份选择,可以通过一些自定义代码来实现。虽然 EasyUI 没有直接提供这种功能,但可以通过自定义 formatter 和 parser 方法,以及修改 onShowPanel 事件来实现这个功能。 以下…...
【数据结构】队列(链表实现 + 力扣 + 详解 + 数组实现循环队列 )
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:数据结构 📚本系列文章为个人学…...
02 Go语言操作MySQL基础教程_20240729 课程笔记
概述 如果您没有Golang的基础,应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728 基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相…...
相交链表 - 力扣(LeetCode)C语言
160. 相交链表 - 力扣(LeetCode) (点击前面链接即可查看题目) 一、题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始…...
【Python】基础学习技能提升代码样例3:JSON文本处理
对json的处理,无非是编码和解码两部分 编码:将python数据结构转换为json字符串解码: 将json字符串转换为python数据结构 另外,还有.json文件的读写 一、编码 json.dumps(obj, *, skipkeysFalse, ensure_asciiTrue, check_circularTrue, a…...
最新Yiso智云搜索引擎系统源码/开源PHP源码/修复版
源码简介: 最新Yiso智云搜索引擎系统源码/开源PHP源码/修复版。Yiso 是一个性能非常好的搜索引擎,不仅免费开源,还能当作收录网址的平台来用呢!只需要输入关键词,就能轻松找到相关的搜索结果内容。 1、Yiso 用的是自…...
Anconda 快速常用命令简洁版
目的:简单清楚的使用基本的conda 命令 可能需求 查看项目中的虚拟环境及依赖是否满足需求操作新环境来满足项目或者论文的实现 Anconda 常用命令 conda 查看基础命令1. 进入Anaconda 环境2. 查看版本3.查看有哪些虚拟环境4.激活虚拟环境5. 进入虚拟环境查看6. 退出…...
Android 系统启动动画
一、接着我们把 bootanimation.zip 动画文件 预制到 /system/media/ 目录下: 二、目录/system/media/bootanimation.zip PRODUCT_COPY_FILES \$(LOCAL_PATH)/bootanimation.zip:/system/media/bootanimation.zipPRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST \ /…...
解决antd打开modal时页面自动跳到顶部问题
问题原因:antd的样式中有一行,如下样式代码,这行代码导致了在本来有滚动条的页面底部触发modal弹出时,会自动滚动到页面顶部。 html {overflow-y: scroll; } 解决办法:删除这行代码、或者将html的overflow-y属性改成…...
什么是等保测评2.0,等保测评如何定级
在信息化时代,网络安全已成为国家安全的重要组成部分。为了应对日益复杂的网络安全形势,我国推出了网络安全等级保护制度,其中等保测评是评估信息系统安全防护能力的关键环节。本文将深入探讨等保2.0的测评流程和定级标准,以揭示其…...
【嵌入式英语教程--6】C语言中的数组与指针
C语言中的数组与指针 英文原文 Arrays and pointers are fundamental concepts in the C programming language. An array is a collection of elements of the same data type stored in contiguous memory locations. Arrays can be used to store and manipulate sequence…...
RocketMQ 中的同步发送
在现代分布式系统中,消息队列是实现异步通信和解耦的重要组件。Apache RocketMQ 是一款高性能、高吞吐量的分布式消息中间件,广泛应用于电商、金融等领域。本文将详细介绍 RocketMQ 中的同步发送,包括其原理、应用场景、代码示例及注意事项。…...
c语言指针2
文章目录 一、void * 指针二、const关键字1.const修饰变量2.const修饰指针变量2. 1 const放在*的右边2. 2 const放在*的左边2. 3 总结 三、指针的运算3. 1指针的加减运算3. 2 指针 - 指针3. 3 指针的关系运算 四、野指针4. 1 什么叫野指针?4. 1 野指针的成因4.1.1 指…...
十七、openCV教程 图像轮廓
一、图像轮廓 图像轮廓是具有相同颜色或灰度的连续点的曲线.轮廓在形状分析和物体的检测和识别中很有用。 轮廓的作用:.用于图形分析、物体的识别和检测 注意点: 为了检测的准确性,需要先对图像进行二值化或Canny操作。 画轮廓时会修改输入的图像,如…...
基于视觉的语义匹配见多了,那基于雷达的呢?
论文题目: LiDAR-based HD Map Localization using Semantic Generalized ICP with Road Marking Detection 论文作者: Yansong Gong, Xinglian Zhang, Jingyi Feng, Xiao He and Dan Zhang 作者单位:北京驭势科技有限公司 导读ÿ…...
基于Python的物流管理系统毕业设计源码
博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在开发一套基于Python的物流管理系统,以提升物流企业的运营效率和管理水平。具体而言,研究目的可从以下几个方面进行阐述&#x…...
Linux 系统调用实现原理
Linux 系统调用实现原理 系统调用的重要性 作为科技创业者,我深刻理解系统调用在操作系统中的核心地位。系统调用是用户空间与内核空间交互的桥梁,是应用程序访问操作系统服务的唯一途径。深入理解系统调用的实现原理,对于系统性能优化和安全…...
Python类与对象实战:从简历模板到动态方法绑定的完整指南
Python类与对象实战:从简历模板到动态方法绑定的完整指南 面向对象编程(OOP)是现代编程语言的核心范式之一,而Python作为一门多范式语言,其面向对象特性尤为强大且易于使用。本文将通过构建一个简历模板系统的完整案例…...
Git-RSCLIP快速部署指南:一键启动,轻松搭建你的遥感图像搜索引擎
Git-RSCLIP快速部署指南:一键启动,轻松搭建你的遥感图像搜索引擎 1. 引言:遥感图像搜索的新利器 在遥感图像分析领域,我们经常面临这样的挑战:如何从海量卫星和航拍图像中快速找到特定目标?传统方法需要人…...
别再手动配环境了!用Docker Compose一键部署GeoServer,5分钟搞定TIF影像发布
5分钟极速部署GeoServer:Docker Compose全自动化实战指南 每次新项目启动都要重复配置GeoServer?还在为环境变量和端口冲突头疼?GIS开发中最耗时的从来不是业务逻辑,而是这些本该自动化的基础设施搭建。今天我们就用Docker Compo…...
v-md-editor进阶技巧:如何在Vue2中实现markdown与HTML的双向转换
Vue2项目中v-md-editor深度应用:Markdown与HTML双向转换实战指南 在内容管理系统、技术文档平台或博客应用中,Markdown与HTML格式的相互转换是开发者常遇到的核心需求。v-md-editor作为Vue生态中功能强大的Markdown编辑器,其双向转换能力往往…...
Nix系统修复终极指南:快速解决包管理问题与数据恢复
Nix系统修复终极指南:快速解决包管理问题与数据恢复 【免费下载链接】nix Nix, the purely functional package manager 项目地址: https://gitcode.com/gh_mirrors/ni/nix Nix作为一款纯粹函数式的包管理器,以其独特的依赖管理和环境隔离机制受到…...
FPGA资源优化指南:use_dsp48和SIMD模式在Vivado中的实战技巧
FPGA资源优化实战:DSP48E的SIMD模式与use_dsp48高阶应用 在5G信号处理、雷达系统等高性能计算场景中,FPGA开发者经常面临资源利用率与计算性能的双重挑战。Xilinx 7系列及UltraScale架构中的DSP48E1/DSP48E2切片作为专用计算单元,其灵活配置…...
别再只会用ST-Link了!手把手教你用串口给STM32F103C8T6远程更新固件(IAP实战)
突破有线束缚:基于串口的STM32F103C8T6固件无线更新实战指南 当你的STM32开发板被嵌入产品外壳深处,当生产线上的设备需要批量升级,当野外部署的传感器需要修复漏洞——传统ST-Link烧录方式立刻显得笨拙不堪。本文将揭示如何仅用5元的USB转TT…...
eUICC 配置文件结构 (Profile Structure) 的核心组件与权限管理解析
1. eUICC配置文件结构入门指南 想象一下你的手机SIM卡突然变成了一张"万能卡"——这就是eUICC技术带来的变革。与传统SIM卡不同,eUICC(嵌入式通用集成电路卡)最神奇的地方在于它能远程切换不同运营商的配置文件(Profil…...
