java实现计算复杂数学表达式
用过python或者PHP的同学应该知道,它们都有个eval函数,这个函数真的是好用啊,比如我算数的时候就喜欢用python的控制台来当做计算器。比如:
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> print('公积金每年存多少?',3500*0.12*2*12)
公积金每年存多少? 10080.0
>>> print('余额宝年利率0.27的话,一万每天利息多少?',1*270/365)
余额宝年利率0.27的话,一万每天利息多少? 0.7397260273972602
>>> 400+10/(120-20)+400
800.1
>>>
但java貌似没有。
以下是我自己的实现。
思路:
思路就是分两步来进行
- 翻译输入的数学表达式,也就是中缀表达式转后缀表达式。例如
a+b*(c-d)
转为后缀表达式就是abcd-*+
- 对后缀表达式计算结果。这里用到了栈存储计算结果,每次都是对两个数计算,例如
abcd-*+
,计算方法是先从头遍历,数字直接入栈,当遇到计算符,则从栈顶取出来两个数计算然后再把结果压栈,最终全部计算完之后栈里面只剩下一个元素就是结果。
1.中缀表达式转后缀表达式
实现转换的基本步骤如下:
- 初始化一个运算符栈。
- 从算数表达式输入的字符串中依次从左向右每次读取一个字符。
- 如果当前字符是操作数,则直接填写到后缀表达式。
- 如果当前字符是(左括号,将其压入运算符栈(第一步定义)。
- 如果当前字符为运算符,则
- 当运算符栈为空,则将其压入运算符栈。
- 当此运算符的优先级高于栈顶元素的时候,则将此运算符压入运算符栈;否则,弹出栈顶运算符到后缀表达式,并且将当前运算符压栈。回到步骤2.
- 如果当前字符是)右括号,反复将栈顶元素弹出到后缀表达式,直到栈顶元素是左括号(为止,并将左括号从栈中弹出丢弃。
- 如果读取还未完成,回到步骤2.
- 如果读取完成,则将栈中剩余的运算符依次弹出到后缀表达式。
private static String transfer(String mathStr) {// 标记输出结果StringBuilder result = new StringBuilder();// 1.初始化一个运算符栈。Stack<Character> stack = new Stack();if (mathStr == null || mathStr.length() == 0) {return null;}System.out.println("--------------");System.out.println("中缀表达式:" + mathStr);char[] arr = mathStr.toCharArray();for (int i = 0; i < arr.length; i++) {// 2.从算数表达式输入的字符串中依次从左向右每次读取一个字符。char s = arr[i];// 3.如果当前字符是操作数,则直接填写到后缀表达式。if (Character.isDigit(s)) {result.append(s);}// 4.如果当前字符是(左括号,将其压入运算符栈(第一步定义)。else if ('(' == s) {stack.push(s);}// 5.如果当前字符为运算符,则else if ('+' == s || '-' == s || '*' == s || '/' == s) {if (!stack.isEmpty()) {char stackTop = stack.pop();// 当此运算符的优先级高于栈顶元素的时候,则将此运算符压入运算符栈if (compare(s, stackTop)) {stack.push(stackTop);stack.push(s);}// 否则,弹出栈顶运算符到后缀表达式,并且将当前运算符压栈。回到步骤2.else {result.append(stackTop);stack.push(s);}}// 5.1.当运算符栈为空,则将其压入运算符栈。else {stack.push(s);}}// 6.如果当前字符是)右括号,反复将栈顶元素弹出到后缀表达式,直到栈顶元素是左括号(为止,并将左括号从栈中弹出丢弃。else if (s == ')') {while (!stack.isEmpty()) {char item = stack.pop();if (item != '(') {result.append(item);} else {break;}}}}while (!stack.isEmpty()) {result.append(stack.pop());}System.out.println("后缀表达式:" + result.toString());return result.toString();}//比较优先级private static boolean compare(char s, char item) {if (item == '(') {return true;}if (s == '*' || s == '/') {if (item == '+' || item == '-') {return true;}}return false;}
2.计算结果
每次都是对两个数计算,例如 abcd-*+
,计算方法是先从头遍历,数字直接入栈,当遇到计算符,则从栈顶取出来两个数计算然后再把结果压栈,最终全部计算完之后栈里面只剩下一个元素就是结果。
private static int calculate(String transferToPostfix) {Stack<Integer> stack = new Stack();char[] c = transferToPostfix.toCharArray();int a, b;for (int i = 0; i < c.length; i++) {switch (c[i]) {case '+':a = Integer.valueOf(stack.pop().toString());b = Integer.valueOf(stack.pop().toString());stack.push(b + a);break;case '-':a = Integer.valueOf(stack.pop().toString());b = Integer.valueOf(stack.pop().toString());stack.push(b - a);break;case '*':a = Integer.valueOf(stack.pop().toString());b = Integer.valueOf(stack.pop().toString());stack.push(b * a);break;case '/':a = Integer.valueOf(stack.pop().toString());b = Integer.valueOf(stack.pop().toString());stack.push(b / a);break;default:Character d = c[i];stack.push(Integer.valueOf(d.toString()));break;}}return stack.pop();}
3.测试
public static void main(String[] args) {System.out.println("计算结果:" + calculate(transferToPostfix("1+2*(3-4)")));System.out.println("计算结果:" + calculate(transferToPostfix("3-2/3")));System.out.println("计算结果:" + calculate(transferToPostfix("2*3-9/(4-1)")));
}
--------------
中缀表达式:1+2*(3-4)
后缀表达式:1234-*+
计算结果:-1
--------------
中缀表达式:3-2/3
后缀表达式:323/-
计算结果:3
--------------
中缀表达式:2*3-9/(4-1)
后缀表达式:23*941-/-
计算结果:3
这里我使用了char来存储运算单位,因此只能运算个位数,如果要运算多位数或者是带小数的,把char类型换成自己封装的就可以了,思路都是一样的。
java实现计算复杂数学表达式相关推荐
- java面向对象实现表达式计算,java面向对象课程设计-数学表达式计算器
项目简介 设计一个计算器,其能够: 1)由用户输入一个简单的四则运算表达式,求出其计算结果后显示. 2)特殊数学函数,如:绝对值.取整.三角函数.倒数.平方根.平方.立方等. 3)对一定范围内的数字将 ...
- 字符串转成可计算的数学表达式
1. JavaScript eval() 函数:计算或执行参数.如果参数是表达式,则 eval() 计算表达式.如果参数是一个或多个 JavaScript 语句,则 eval() 执行这些语句. va ...
- 华为机试 计算加减乘除数学表达式的结果
源 代码链接http://codepad.org/s7KRVYiV #include <stdlib.h> #include <stdio.h> #include < ...
- 计算复杂数学表达式的值
S = (2^2/(1*3))*(4^2/(3*5))*.....(2n)^2*(2n-1)*(2n+1) 例如,输入n = 100时,函数的值为1.566893 代码如下: #include < ...
- 编写python程序输出数学表达式_Python基本编程题
问题1:仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留3位. ...
- java数学计算表达式_Java初学者:内建函数计算简单的数学表达式
这个应该在之前写的,忘记了,补上 这次我们说一下如何用java计算数学表达式的值,比如,我们要计算sin(pi/3) + cos(pi/6) + 5.6^3,怎么计算呢?这里我们需要用到java的ma ...
- Java数学表达式计算(中缀转后缀表达式)
文章目录 前言 中缀表达式转后缀表达式 计算后缀表达式 计算形式公式 声明 前言 数学计算的加减乘除人脑算很简单,但是放到计算中却需要进行一些转换,在正式写Java计算数学表达式前,我们需要先来介绍两 ...
- java 中缀转后缀并计算_Java实现表达式计算(中缀转后缀)
定义: 中缀表达式:我们平时写的数学表达式一般为中缀表达式,如"5+2*(3*(3-1*2+1))",直接拿中缀表达式直接让计算机计算表达式的结果并不能做到. 后缀表达式:把中缀表 ...
- java 数学表达式解析插件_数学表达式解析-JAVA版
1 .工具介绍 String exp = "v>=10&&v<=2000&&v%10==0"; 在 js 中,能够直接运行 eval 得 ...
最新文章
- DC-RC加固修补型砂浆
- [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性
- java逻辑移位和算术移位,关于对移位运算的理解
- 硬核!C语言八大排序算法,附动图和详细代码解释!
- 报错Cannot determine embedded database driver class for database type NONE解决方法
- vue 打包后本地先自己启动服务 anywhere 非常好用
- if...else 应用(猜幸运数字)
- 单元格赋值与联动 例:C1值赋予D1 ,并将D1的值传给图表元素联动
- 嵌入式用HTTP请求下载bin文件
- 用Python解决女朋友看电影没字幕的需求
- excel切片器_如何快速做出酷炫的Excel动态图表?
- python编写木马攻击_Python编写简易木马程序
- 微信红包和转账有哪些区别?原来还有这些不同!涨知识了
- Deep learning for minimum mean-square error approaches to speech enhancement
- SQL行转列,列转行
- SpringBoot 入参校验
- php视频提取音频,怎么提取视频中音频文件?视频文件如何分离提取出音频文件?视频转换成音频的方法...
- css简单样式(旋转正方形、纸片旋转、轮播图3D、简单轮播图)
- Golang使用qrcode生成二维码,以及生成带logo的二维码
- JZOJ3461【小麦亩产一千八(kela)】
热门文章
- 测试人即用宝典,全网最全的功能测试点,有这一篇完全足够......
- PPT改变图形阴影的颜色
- 怎么用计算机画动漫,【精选】如何用电脑学画漫画?
- mysql insert id菜鸟_MySQL 插入数据
- 你了解Simulation中不同单元有何区别吗?
- NotePad++的查找的用法(包含正则表达式)
- Spring Bean生命周期:Bean的初始化阶段
- uni-app实战社区交友
- 中企动力携手河南卫特解锁网络营销新模式
- 微信小程序 手写签名_微信小程序实现手写签字