letcode 16.26. 计算器。
给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

表达式仅包含非负整数,+, - ,*,/ ,(,)四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: "3+2*2"
输出: 7

示例 2:

输入: " 3/2 "
输出: 1

示例 3:

输入: " 3+5 / 2 "
输出: 5

说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

分析一个复杂的过程:

// 超级计算器:利用两个栈,一个数字栈,一个操作栈。过程利用逆序波兰表达式。
str="12*(2+(3+(4+2*(5+6))))$"; $为结束符号  看看如何做入栈出栈操作的。
用sb存上次的操作数字,这是为了解决大数字比如22  nowChar存当前字符 len为sb的length
详细分析:
i=0: 1 是数字 暂时存sb='1' nowChar='1'
i=1: 2 是数字 暂时存sb='12' nowChar='2'
i=2: * 不是数字 len>0 将sb入栈numStack[12.0], len=0,* 入栈operStack[*] nowChar='*'
i=3: ( 不是数字 len=0 sb不入栈,( 入栈operStack[*,(] nowChar='('
i=4: 2 是数字 暂时存sb='2' nowChar='2'
i=5: + 不是数字 len>0 将sb入栈numStack[12.0,2.0], len=0,+ 入栈operStack[*,(,+] nowChar='+'
i=6: ( 不是数字 len=0 sb不入栈,( 入栈operStack[*,(,+,(] nowChar='('
i=7: 3 是数字 暂时存sb='3' nowChar='3'
i=8: + 不是数字 len>0 将sb入栈numStack[12.0,2.0,3.0], len=0,+ 入栈operStack[*,(,+,(,+] nowChar='+'
i=9: ( 不是数字 len=0 sb不入栈,( 入栈operStack[*,(,+,(,+,(] nowChar='('
i=10: 4 是数字 暂时存sb='4' nowChar='4'
i=11: + 不是数字 len>0 将sb入栈numStack[12.0,2.0,3.0,4.0], len=0,+ 入栈operStack[*,(,+,(,+,(,+] nowChar='+'
i=12: 2 是数字 暂时存sb='2' nowChar='2'
i=13: * 不是数字 len>0 将sb入栈numStack[12.0,2.0,3.0,4.0,2.0], len=0,* 入栈operStack[*,(,+,(,+,(,+,*] nowChar='*'
i=14: ( 不是数字 len=0 sb不入栈,( 入栈operStack[*,(,+,(,+,(,+,*,(] nowChar='('
i=15: 5 是数字 暂时存sb='5' nowChar='5'
i=16: + 不是数字 len>0 将sb入栈numStack[12.0,2.0,3.0,4.0,2.0,5.0], len=0,+ 入栈operStack[*,(,+,(,+,(,+,*,(,+] nowChar='+'
i=17: 6 是数字 暂时存sb='6' nowChar='6'
i=16: ) 不是数字 len>0 将sb入栈numStack[12.0,2.0,3.0,4.0,2.0,5.0,6.0], len=0,) 解栈标记 nowChar=')' 计算括号内的内容,直到找到成对'(':首先:operStack出栈'+' 不是'('。那么根据数据栈弹出两个数据和当前操作符计算,5.0+6.0=11.0并放入数据栈numStack[12.0,2.0,3.0,4.0,2.0,11.0],operStack[*,(,+,(,+,(,+,*,(].继续找operStack出栈'(' 组成一对,'('弹出并break出当前循环operStack[*,(,+,(,+,(,+,*]
i=17: ) 不是数字 len=0 sb不入栈) 解栈标记 nowChar=')' 计算括号内的内容,直到找到成对'(':首先:operStack出栈'*' 不是'('。那么根据数据栈弹出两个数据和当前操作符计算,2.0+11.0=22.0并放入数据栈numStack[12.0,2.0,3.0,4.0,22.0],operStack[*,(,+,(,+,(,+].继续找operStack出栈'+' 不是'(' 根据数据栈弹出两个数据和当前操作符计算,4.0+22.0=26.0入栈numStack[12.0,2.0,3.0,26.0] operStack[*,(,+,(,+,(]。继续。出栈'('组成一对,'('弹出并break出当前循环operStack[*,(,+,(,+]
i=18到i=21 重复上面i7的过程得到numStack[12.0,31.0] operStack[*]
i=22 $ 为结束符号 len=0.说明上面入栈出栈完成。还需要查栈中是否操作完成以及len不为0的情况。栈不为空,继续计算12.0*31.0=372.0 numStack[372.0] operStack[]
到此计算完成。

简单优先级计算分析:

// 超级计算器:利用两个栈,一个数字栈,一个操作栈。过程利用逆序波兰表达式。
str="3*4+1$"; $为结束符号  看看如何做入栈出栈操作的。
用sb存上次的操作数字,这是为了解决大数字比如22  nowChar存当前字符 len为sb的length
再来分析普通的情况:
i=0: numStack[] operStack[]
i=1: numStack[3] operStack[*]
i=2: numStack[3,4] operStack[*]
i=3: numStack[3,4,1] operStack[*,+]
i=4: $结束符号 numStack[3,4,1] operStack[*,+]
计算过程:(1+4)*3显然不对。* /的优先级应该大于+ -
所以要做下一次计算操作来前,operStack拿操作栈的栈顶符,是高优先级则计算。
i=3: + 是计算+/-符号 operStack[*]弹出是* /高优先级计算,则先计算3*4=12,入栈numStack[12].
再继续。

实际代码:

package com.jvm.stu;import java.util.Stack;
import java.util.regex.Pattern;public class Main {static final Pattern EXGRE_NUM = Pattern.compile("^[0-9\\\\.]$");public static void main(String[] args) {// 为了方便计算我增加了一个$表示结束System.out.println(calculate("3*4+2$"));// System.out.println(calculate("2*(2+(3+(4+2*(5+6))))$"));}// 贴近计算改为返回doublepublic static double calculate(String s) {Stack<Double> numStack= new Stack<>();Stack<Character> operStack = new Stack<>();// 用于处理123,0.123的情况StringBuilder sb = new StringBuilder();char nowChar = '$';for (int i = 0; i < s.length(); ++i) {char ch = s.charAt(i);if (isNum(ch)) {sb.append(ch);} else if (isSymbol(ch)) {if (sb.length() > 0) {numStack.push(Double.valueOf(sb.toString()));sb.setLength(0);}// + - 处理 比如情况 1+(-2)if (isSign(ch) && ('(' == nowChar || '$' == nowChar || isOper(nowChar))) {sb.append(ch);} else if (')' == ch) {while (!operStack.isEmpty()) {if (operStack.peek() == '(') {operStack.pop();break;}calcu(numStack, operStack);}} else {if (!operStack.isEmpty() && isSign(ch) && isHighOper(operStack.peek())) {// 优先级高先计算calcu(numStack, operStack);}operStack.push(ch);}}nowChar = ch;}// 检查计算完全if (sb.length() > 0) {numStack.push(Double.valueOf(sb.toString()));}while (!operStack.isEmpty()) {calcu(numStack, operStack);}return numStack.pop();}private static void calcu(Stack<Double> numStack, Stack<Character> operStack) {Double num1 = Double.valueOf(numStack.pop());// 当前弹出,为空栈if (numStack.isEmpty()) {numStack.push(num1);}Double num2 = Double.valueOf(numStack.pop());switch (operStack.pop()) {case '+': numStack.push(num2 + num1); break;case '-': numStack.push(num2 - num1); break;case '*': numStack.push(num2 * num1); break;case '/': numStack.push(num2 / num1); break;case '(': operStack.push('('); return;default:break;}}// 数字public static boolean isNum(char ch){return EXGRE_NUM.matcher(ch + "").find();}// 优先级public static boolean isHighOper(char ch){return ch == '*' || ch == '/';}// 正负public static boolean isSign(char ch){return ch == '-' || ch == '+';}// 操作符public static boolean isOper(char ch){return isSign(ch) || isHighOper(ch);}public static boolean isSymbol(char ch){return isOper(ch) || '(' == ch || ')' == ch;}
}

这里存在优化的点:凡是能用stack实现的都能用linkedList实现,后者效率更高。不累述。只是将两个操作栈换了就行。实际算法中能不用Stack就不用,最好都用linkedList。

计算:34+2$
Stack下运行时间:

linkedList下运行时间:

复杂计算:2
(2+(3+(4+2*(5+6))))$
Stack下运行时间:

linkedList下运行时间:

从上面可以看到,简单计算Stack快,复杂计算linkedList。优化从来不是一概而论,具体场景具体优化。

letcode 超级计算器相关推荐

  1. 涨跌因子计算器下载哪里下载_网易超级计算器appv1-网易超级计算器v1下载

    超级计算器app是一款强大的计算机软件,超级计算器app是网易推出的,其强大的计算功能已经不再拘泥于普通的计算器只能计算加减乘除了,更多的功能足以满足所有人的计算需求,无论你是小学还是大学都能帮的到你 ...

  2. 科学计算机 app,‎App Store 上的“超级计算器-科学计算机”

    超级计算器,比原生计算器更好用的计算器.包含经典计算器.科学计算器.实时汇率换算器以及单位换算器的四合一全功能计算器工具. 超级计算器提供强大的历史记录功能.语音读数功能,独家提供[结果继承]功能,计 ...

  3. python小欢喜(三)超级计算器

    在日常生活中,我们经常用到计算器,计算器可以帮助我们快速得到数学算式的结果.在电脑上,也有计算器软件,计算器软件的界面与实际的计算器很类似,功能更加强大. 如果学会了python语言,我们将拥有一个比 ...

  4. 超级计算机app不能解方程,有了这款被 App Store 官方推荐的超级计算器,该把手头的计算器扔了...

    原标题:有了这款被 App Store 官方推荐的超级计算器,该把手头的计算器扔了 网易有道又发布了一款广受好评的新产品 -- 「超级计算器」,应用一上线就被 App Store 官方首页推荐,短时间 ...

  5. java超级计算器,jdk自带类

    2019独角兽企业重金招聘Python工程师标准>>> package lcr;import java.math.BigInteger;/*** 超级计算器* * @author L ...

  6. 有道科学计算机,网易有道超级计算器获App Store推荐 打造随身数学帮手

    近日,网易有道正式发布iOS版超级计算器,甫一上线即获得App Store首页精品推荐,并在短时间内迅速爬升,跻身效率榜前五.作为一款全新的APP,超级计算器的智能化程度极高.它是目前国内仅有的定积分 ...

  7. 超级计算器android,超级计算器 - 一上线就被AppStore官方推荐的超级计算器 - Android 应用 - 【最美应用】...

    这款计算器,能直接解方程求积分 在「超级计算器」中解方程,就像打字一样简单.你仅需要把方程式像打字一样完整地输入进去,再点击「求解方程组」,就可以直接得到方程的解,终于不用再拐弯抹角地分解.代入了! ...

  8. 会解方程会画图的超级计算器

    会解方程会画图的超级计算器 这个计算器功能强大,可以解方程.解不等式,判断素数,比较大小,映射,筛选,精度计算,求导,求积分,求极限,绘制图形等多项功能,操作简单. # coding: GB2312 ...

  9. android 上最强的计算器,史上最强超级计算器发布!完爆科学计算器

    近日,网易正式发布有道超级计算器,日常计算.分式化简.方程求解.多项式分解和展开.微积分,统统包含其中,比科学计算器还要强大. 据介绍,有道超级计算器可以自动显示日常计算的结果,并可以对计算结果进行操 ...

最新文章

  1. 一位资深程序员面试Python工程师的岗位心得和历程
  2. NAC网络访问控制,你需要知道的!
  3. 国外centos服务器配置epel源
  4. java 中 statent,【行为型模式】状态模式(state)之23种java设计模式
  5. 【转】C# HMAC Sha1 生成签字
  6. 《How to Write and Publish a Scientifc Paper》个人笔记
  7. 开源 -- 机器学习相关报道
  8. orientation|keyboardHidden
  9. chm文件导入java_java API的chm文件制作
  10. 分辨率计算机英语,各种分辨率的英文缩写
  11. Android App Dark Theme(暗黑模式)适配指南
  12. 职场邮件的十大忌讳,你犯了吗?
  13. 2022VS CORD安装教程
  14. bundle包是什么意思_【Xcode小技巧】生成Bundle包
  15. 基于pandas的粗糙集依赖度约简算法思路及实现
  16. “DDS” 你为什么要丢数据丫
  17. 世界500强公司网站一览
  18. python操作微信手机端下载_用PYTHON玩微信(非常详细)
  19. 用C++制作跳棋游戏,模式任你选,怂了算我输!
  20. 营销狂人杜国楹的两大顶级思维

热门文章

  1. python爬虫自学1-爬取静态网页-2022-02-10
  2. 路行助手使用教程_路行助手软件下载-路行助手app下载V6.6.6 - 优游网
  3. 【一建、一造经验分享】一建挺难的,要坚持才能得到
  4. 2003-2020年年地级市环境污染数据集/2003-2020年地级市环境污染数据集地级市工业三废排放量数据地级市工业废水排放量、地级市工业二氧化硫排放量
  5. php amr 转mp3 oss,ffmpeg 视频转码例子集合
  6. NLP(二十六)限定领域的三元组抽取的一次尝试
  7. 【信息论是什么?信息,消息和信号?】信息论与编码入门(一)
  8. 如何用人工智能秒杀超级马里奥游戏
  9. Ubuntu安装无线网卡(USB)驱动
  10. 音乐网站毕业设计html,静态音乐网站设计(毕业论文).doc