1. import java.util.Stack;
  2. /**
  3. * 利用栈,进行四则运算的类
  4. * 用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack,一个用来保存计算优先符priStack
  5. *
  6. * 基本算法实现思路为:用当前取得的运算符与priStack栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;
  7. * 若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;
  8. *  若小于,则同理,取出栈顶元素运算,将结果入操作数栈。各个优先级'(' > '*' = '/' > '+' = '-' > ')'
  9. *
  10. */
  11. public class Operate {
  12. private Stack<Character> priStack = new Stack<Character>();// 操作符栈
  13. private Stack<Integer> numStack = new Stack<Integer>();;// 操作数栈
  14. /**
  15. * 传入需要解析的字符串,返回计算结果(此处因为时间问题,省略合法性验证)
  16. * @param str 需要进行技术的表达式
  17. * @return 计算结果
  18. */
  19. public int caculate(String str) {
  20. // 1.判断string当中有没有非法字符
  21. String temp;// 用来临时存放读取的字符
  22. // 2.循环开始解析字符串,当字符串解析完,且符号栈为空时,则计算完成
  23. StringBuffer tempNum = new StringBuffer();// 用来临时存放数字字符串(当为多位数时)
  24. StringBuffer string = new StringBuffer().append(str);// 用来保存,提高效率
  25. while (string.length() != 0) {
  26. temp = string.substring(0, 1);
  27. string.delete(0, 1);
  28. // 判断temp,当temp为操作符时
  29. if (!isNum(temp)) {
  30. // 1.此时的tempNum内即为需要操作的数,取出数,压栈,并且清空tempNum
  31. if (!"".equals(tempNum.toString())) {
  32. // 当表达式的第一个符号为括号
  33. int num = Integer.parseInt(tempNum.toString());
  34. numStack.push(num);
  35. tempNum.delete(0, tempNum.length());
  36. }
  37. // 用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;
  38. // 若小于,则同理,取出栈顶元素运算,将结果入操作数栈。
  39. // 判断当前运算符与栈顶元素优先级,取出元素,进行计算(因为优先级可能小于栈顶元素,还小于第二个元素等等,需要用循环判断)
  40. while (!compare(temp.charAt(0)) && (!priStack.empty())) {
  41. int a = (int) numStack.pop();// 第二个运算数
  42. int b = (int) numStack.pop();// 第一个运算数
  43. char ope = priStack.pop();
  44. int result = 0;// 运算结果
  45. switch (ope) {
  46. // 如果是加号或者减号,则
  47. case '+':
  48. result = b + a;
  49. // 将操作结果放入操作数栈
  50. numStack.push(result);
  51. break;
  52. case '-':
  53. result = b - a;
  54. // 将操作结果放入操作数栈
  55. numStack.push(result);
  56. break;
  57. case '*':
  58. result = b * a;
  59. // 将操作结果放入操作数栈
  60. numStack.push(result);
  61. break;
  62. case '/':
  63. result = b / a;// 将操作结果放入操作数栈
  64. numStack.push(result);
  65. break;
  66. }
  67. }
  68. // 判断当前运算符与栈顶元素优先级, 如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈
  69. if (temp.charAt(0) != '#') {
  70. priStack.push(new Character(temp.charAt(0)));
  71. if (temp.charAt(0) == ')') {// 当栈顶为'(',而当前元素为')'时,则是括号内以算完,去掉括号
  72. priStack.pop();
  73. priStack.pop();
  74. }
  75. }
  76. } else
  77. // 当为非操作符时(数字)
  78. tempNum = tempNum.append(temp);// 将读到的这一位数接到以读出的数后(当不是个位数的时候)
  79. }
  80. return numStack.pop();
  81. }
  82. /**
  83. * 判断传入的字符是不是0-9的数字
  84. *
  85. * @param str
  86. *            传入的字符串
  87. * @return
  88. */
  89. private boolean isNum(String temp) {
  90. return temp.matches("[0-9]");
  91. }
  92. /**
  93. * 比较当前操作符与栈顶元素操作符优先级,如果比栈顶元素优先级高,则返回true,否则返回false
  94. *
  95. * @param str 需要进行比较的字符
  96. * @return 比较结果 true代表比栈顶元素优先级高,false代表比栈顶元素优先级低
  97. */
  98. private boolean compare(char str) {
  99. if (priStack.empty()) {
  100. // 当为空时,显然 当前优先级最低,返回高
  101. return true;
  102. }
  103. char last = (char) priStack.lastElement();
  104. // 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。
  105. if (last == '(') {
  106. return true;
  107. }
  108. switch (str) {
  109. case '#':
  110. return false;// 结束符
  111. case '(':
  112. // '('优先级最高,显然返回true
  113. return true;
  114. case ')':
  115. // ')'优先级最低,
  116. return false;
  117. case '*': {
  118. // '*/'优先级只比'+-'高
  119. if (last == '+' || last == '-')
  120. return true;
  121. else
  122. return false;
  123. }
  124. case '/': {
  125. if (last == '+' || last == '-')
  126. return true;
  127. else
  128. return false;
  129. }
  130. // '+-'为最低,一直返回false
  131. case '+':
  132. return false;
  133. case '-':
  134. return false;
  135. }
  136. return true;
  137. }
  138. public static void main(String args[]) {
  139. Operate operate = new Operate();
  140. int t = operate.caculate("(3+4*(4*10-10/2)#");
  141. System.out.println(t);
  142. }
  143. }

java 四则运算 栈的实现相关推荐

  1. 堪称神级的 Java 技术栈手册火了!

    本文是为了帮大家快速回顾 Java 中知识点,这套面试手册涵盖了诸多 Java 技术栈的面试题和答案,相信可以帮助大家在最短的时间内用作面试复习,能达到事半功倍效果. 本来想将文件上传到 GitHub ...

  2. java客服系统_阿里Java内部资料:2020最全Java技术栈(架构篇+算法篇+大数据)

    我只截图不说话,PPT大全,氛围研发篇.算法篇.大数据.Java后端架构!除了大家熟悉的交易.支付场景外,支撑起阿里双十一交易1682亿元的"超级工程"其实包括以下但不限于客服.搜 ...

  3. 探究Java虚拟机栈

    前言 Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区:另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存.今天我就 Java 虚拟机栈做 ...

  4. java进出栈_JVM函数调用:Java出入栈

    JVM函数调用:Java出入栈 JVM函数调用:Java出入栈 目录 局部变量表 索引复用 垃圾回收 栈数据区 栈上分配 线程作为系统运算调度的最小单位,在JVM中线程的行为体现就是函数调用,函数调用 ...

  5. java 取栈顶元素_《Java实战之内存模型》详解篇

    内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行 JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JVM的高效稳定运行 不同的JV ...

  6. Java中栈和队列的用法 Stack And Queue

    Java中栈和队列的用法 栈的实现 使用Java的集合类Stack boolean isEmpty();//判断当前栈是否为空,等价于empty(); synchronized E peek();// ...

  7. 46栈内存溢出、内存区域(程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区、直接内存、内存溢出)与内存溢出(对象实例化分析)

    46.什么情况下会发生栈内存溢出 46.1.Java 内存区域与内存溢出 46.1.1.内存区域 46.1.1.1.程序计数器 46.1.1.2.Java 虚拟机栈 46.1.1.3.本地方法栈 46 ...

  8. 12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置

    12.JDK1.8 JVM运行时数据区域概览 12.1.JDK1.8 JVM运行时数据区域概览 12.2.各区域介绍 12.3.各区域介绍 12.3.1.程序计数器 12.3.2.Java虚拟机栈 1 ...

  9. 9012年大厂面试题合集:Java技术栈为什么竞争越来越激烈?

    就今年大环境来看,跳槽成功的难度比往年高很多,一个明显的感受:今年的Java技术栈面试,无论一面还是二面,都特别考验Java程序员的技术功底. 最近有人搜集了93套腾讯.阿里.美团.百度.网易等公司9 ...

最新文章

  1. hdu5692【dfs序】【线段树】
  2. Java工程师知识图谱
  3. Java Error(一)
  4. 看着手机会让您晕眩吗? 禁用动画
  5. 《西线无战事》:合上书的那一刻:只想痛哭
  6. php get请求_JWT+PHP实现登录认证+令牌分发的修改
  7. Linux中/etc/init.d
  8. ElementUI实现表单校验
  9. 第三章 3.3 DI自动装配 --《跟我学Spring》笔记 张开涛
  10. 欧几里得空间与希尔伯特空间
  11. excel文件修复工具_ArcGIS工具箱使用技巧汇总
  12. 《算法导论》第16章-贪心算法 16.1-活动选择问题(含C++代码)
  13. Xshell下载文件到本地
  14. android解压rar方法,安卓手机如何解压rar/zip/7z等压缩包 详细图解教程
  15. 基层管理者项目管理二三事
  16. RS485为什么需要隔离?什么情况下可以不用隔离?
  17. MyBatis 关联映射
  18. 实验 基本交换机设置
  19. 影响神经网络训练速度的因素
  20. [SV]合并数组和非合并数组

热门文章

  1. 形容等待时间长的句子_雅思听力该如何准确辨别句子结构?学会结构精听,雅思8分轻松get!...
  2. OpenStack(五)——Neutron组件
  3. 免费和开源世界里面有很多好的邮件服务器
  4. 虚拟机和主机文件共享的四种方法
  5. linux怎么制作运行包,简单 RPM 包制作
  6. python 2x可以打么_15分钟让你了解Python套路,看你能不能坚持的住
  7. mac终端一次命令在多个虚拟机执行_Windows给力!可以扔掉Linux虚拟机了!
  8. 计算机编程工程师理论知识,结构工程师基础知识点:程序设计语言
  9. linux命令界面下载kettle,kettle在linux环境中打开图形界面-Go语言中文社区
  10. php 上一个月的开始和结束,php获取上一个月的开始与结束时间遇到的问题