用过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貌似没有。

以下是我自己的实现。

思路:

思路就是分两步来进行

  1. 翻译输入的数学表达式,也就是中缀表达式转后缀表达式。例如 a+b*(c-d) 转为后缀表达式就是 abcd-*+
  2. 对后缀表达式计算结果。这里用到了栈存储计算结果,每次都是对两个数计算,例如 abcd-*+ ,计算方法是先从头遍历,数字直接入栈,当遇到计算符,则从栈顶取出来两个数计算然后再把结果压栈,最终全部计算完之后栈里面只剩下一个元素就是结果。

1.中缀表达式转后缀表达式

实现转换的基本步骤如下:

  1. 初始化一个运算符栈。
  2. 从算数表达式输入的字符串中依次从左向右每次读取一个字符。
  3. 如果当前字符是操作数,则直接填写到后缀表达式。
  4. 如果当前字符是(左括号,将其压入运算符栈(第一步定义)。
  5. 如果当前字符为运算符,则
    1. 当运算符栈为空,则将其压入运算符栈。
    2. 当此运算符的优先级高于栈顶元素的时候,则将此运算符压入运算符栈;否则,弹出栈顶运算符到后缀表达式,并且将当前运算符压栈。回到步骤2.
  6. 如果当前字符是)右括号,反复将栈顶元素弹出到后缀表达式,直到栈顶元素是左括号(为止,并将左括号从栈中弹出丢弃。
  7. 如果读取还未完成,回到步骤2.
  8. 如果读取完成,则将栈中剩余的运算符依次弹出到后缀表达式。
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实现计算复杂数学表达式相关推荐

  1. java面向对象实现表达式计算,java面向对象课程设计-数学表达式计算器

    项目简介 设计一个计算器,其能够: 1)由用户输入一个简单的四则运算表达式,求出其计算结果后显示. 2)特殊数学函数,如:绝对值.取整.三角函数.倒数.平方根.平方.立方等. 3)对一定范围内的数字将 ...

  2. 字符串转成可计算的数学表达式

    1. JavaScript eval() 函数:计算或执行参数.如果参数是表达式,则 eval() 计算表达式.如果参数是一个或多个 JavaScript 语句,则 eval() 执行这些语句. va ...

  3. 华为机试 计算加减乘除数学表达式的结果

    源   代码链接http://codepad.org/s7KRVYiV #include <stdlib.h> #include <stdio.h> #include < ...

  4. 计算复杂数学表达式的值

    S = (2^2/(1*3))*(4^2/(3*5))*.....(2n)^2*(2n-1)*(2n+1) 例如,输入n = 100时,函数的值为1.566893 代码如下: #include < ...

  5. 编写python程序输出数学表达式_Python基本编程题

    问题1:仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留3位.‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬ ...

  6. java数学计算表达式_Java初学者:内建函数计算简单的数学表达式

    这个应该在之前写的,忘记了,补上 这次我们说一下如何用java计算数学表达式的值,比如,我们要计算sin(pi/3) + cos(pi/6) + 5.6^3,怎么计算呢?这里我们需要用到java的ma ...

  7. Java数学表达式计算(中缀转后缀表达式)

    文章目录 前言 中缀表达式转后缀表达式 计算后缀表达式 计算形式公式 声明 前言 数学计算的加减乘除人脑算很简单,但是放到计算中却需要进行一些转换,在正式写Java计算数学表达式前,我们需要先来介绍两 ...

  8. java 中缀转后缀并计算_Java实现表达式计算(中缀转后缀)

    定义: 中缀表达式:我们平时写的数学表达式一般为中缀表达式,如"5+2*(3*(3-1*2+1))",直接拿中缀表达式直接让计算机计算表达式的结果并不能做到. 后缀表达式:把中缀表 ...

  9. java 数学表达式解析插件_数学表达式解析-JAVA版

    1 .工具介绍 String exp = "v>=10&&v<=2000&&v%10==0"; 在 js 中,能够直接运行 eval 得 ...

最新文章

  1. DC-RC加固修补型砂浆
  2. [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性
  3. java逻辑移位和算术移位,关于对移位运算的理解
  4. 硬核!C语言八大排序算法,附动图和详细代码解释!
  5. 报错Cannot determine embedded database driver class for database type NONE解决方法
  6. vue 打包后本地先自己启动服务 anywhere 非常好用
  7. if...else 应用(猜幸运数字)
  8. 单元格赋值与联动 例:C1值赋予D1 ,并将D1的值传给图表元素联动
  9. 嵌入式用HTTP请求下载bin文件
  10. 用Python解决女朋友看电影没字幕的需求
  11. excel切片器_如何快速做出酷炫的Excel动态图表?
  12. python编写木马攻击_Python编写简易木马程序
  13. 微信红包和转账有哪些区别?原来还有这些不同!涨知识了
  14. Deep learning for minimum mean-square error approaches to speech enhancement
  15. SQL行转列,列转行
  16. SpringBoot 入参校验
  17. php视频提取音频,怎么提取视频中音频文件?视频文件如何分离提取出音频文件?视频转换成音频的方法...
  18. css简单样式(旋转正方形、纸片旋转、轮播图3D、简单轮播图)
  19. Golang使用qrcode生成二维码,以及生成带logo的二维码
  20. JZOJ3461【小麦亩产一千八(kela)】

热门文章

  1. 测试人即用宝典,全网最全的功能测试点,有这一篇完全足够......
  2. PPT改变图形阴影的颜色
  3. 怎么用计算机画动漫,【精选】如何用电脑学画漫画?
  4. mysql insert id菜鸟_MySQL 插入数据
  5. 你了解Simulation中不同单元有何区别吗?
  6. NotePad++的查找的用法(包含正则表达式)
  7. Spring Bean生命周期:Bean的初始化阶段
  8. uni-app实战社区交友
  9. 中企动力携手河南卫特解锁网络营销新模式
  10. 微信小程序 手写签名_微信小程序实现手写签字