使用栈实现综合计算器(中缀表达式)

1.栈的实际需求

请输入一个表达式,计算式:[722-5+1-5+3-3] ,计算出结果
计算机底层是如何运算得到结果的? 注意不是简单的把算式列出运算,因为我们看这个算式 7 * 2 * 2 - 5, 但是计算机怎么理解这个算式的(对计算机而言,它接收到的就是一个字符串),我们讨论的是这个问题。-> 栈

2.使用栈实现表达式计算的大致思路(详细思路见代码)

(1)创建一个临时变量index索引,来遍历表达式;并创建两个栈空间,一个数栈,一个符号栈。
(2)从前往后遍历字符串,如果是一个数字,就直接入数栈。
(3)如果发现是一个符号,就分为如下情况
(3.1)如果当时符号栈为空就直接入符号栈
(3.2)如果符号栈不为空,就比较当前要入栈的符号与当前栈顶符号做比较;如果要入栈的符号小于等于栈顶符号的优先级,就从数栈中pop出两个数,并且从符号栈中pop出当前栈顶符号,进行运算,并将运算结果重新压入数栈中,然后将当前想要入栈的符号加入符号栈。
(3.3)如果当前的操作符的优先级大于栈顶符号,就直接加入符号栈
(4)当表达式遍历完毕时,就顺序的从数栈和符号栈中pop出相应的数和符号,并运算,之后将结果压入栈中,如此往复,直到符号栈中没有符号为止。
(5)当在数栈中只有一个数字时,就是表达式的结果

3.代码实现

package cn.zzw.algorithm.Stack;import java.util.Scanner;public class ArrayStackDemo1 {public static void main(String[] args) {//测试表达式的计算结果是否正确//当然在这里要思考一下如何处理多位数的加减乘除问题String expression="1000+102*2-6+2*4";//创建两个栈,一个用来存储数字,一个用来存储符号ArrayStack1 numStack=new ArrayStack1(15);ArrayStack1 operStack = new ArrayStack1(15);//定义需要的相关变量int index=0;int num1=0;int num2=0;int operator;int result=0;//将每次扫描得到的char保存到ch中char ch=' ';//用于拼接多位数String keepNum="";//使用while循环遍历表达式while (true){//一次得到expression的每一个字符ch=expression.substring(index,index+1).charAt(0);//判断ch是什么,然后做相应的处理if (operStack.isOper(ch)){//如果是运算符,此时判断当前符号栈是否为空if (!operStack.isEmpty()){//如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符, 就需要从数栈中 pop 出两个数,//在从符号栈中 pop 出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符 号栈if (operStack.priority(ch)<=operStack.priority(operStack.peek())){num1=numStack.pop();num2=numStack.pop();operator=operStack.pop();result=numStack.caluator(num1,num2,operator);//将运算完的结果重新压入栈中numStack.push(result);//然后将当前操作符如符号栈operStack.push(ch);}else{//此时是想要入栈的符号比符号栈顶的符号优先级大,就直接入栈operStack.push(ch);}}else{//如果符号栈为空,就直接将其压入栈中operStack.push(ch);}}//如果是数字,直接入数栈else{//由于有时候是多位数,分析思路如下//1.当处理多位数时,不能发现一个数就直接入栈//2.在处理数字时,需要想expression表达式的index后再看一位,如果是数就进行扫描,如果是符号就入栈//3.需要定义一个字符串变量,用于拼接keepNum+=ch;if (index==expression.length()-1){numStack.push(Integer.parseInt(keepNum));}else{//判断下一个数字是不是数字,如果是就继续扫描,如果是运算符,则入栈//注意是看后一位,不是index++if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))){numStack.push(Integer.parseInt(keepNum));//重要的是要注意把keepNum清空keepNum="";}}}//让index++,并判断是否到expression的最后index++;if(index>=expression.length()){break;}}//当表达式扫描完毕时,则顺序的从数栈和符号栈中弹出相应的数字和符号,并运算,并将运算结果压入栈中while(true){//如果字符栈中字符为空,说明已经计算到了最后一步if(operStack.isEmpty()){break;}num1=numStack.pop();num2=numStack.pop();operator=operStack.pop();result=numStack.caluator(num1,num2,operator);numStack.push(result);}//这时数栈最后一个元素便是最后的结果int result2=numStack.pop();System.out.printf("表达式%s=%d",expression,result2);}
}class ArrayStack1
{private int maxSize;private int[] stack;//使用数组模拟栈private int top=-1;//确定当前符号的优先级,优先级用数字表示public int priority(int oper){if(oper=='*'||oper=='/'){return 1;}else if(oper=='+'||oper=='-'){return 0;}else{//假定目前表达式中只有加减乘除,后面在学逆波兰表达式时还会有()return -1;}}//判断是不是一个运算符public boolean isOper(char val){return val=='+'||val=='-'||val=='*'||val=='/';}//计算方法public int caluator(int num1,int num2,int oper){int result=0;switch (oper){case '+':result=num1+num2;break;case '-':result=num2-num1;break;case '*':result=num1*num2;break;case '/':result=num2/num1;break;default:break;}return result;}//增加一个方法,可以返回当前符号栈的栈顶的值,但不是真正的poppublic int peek(){return stack[top];}//构造器public ArrayStack1(int maxSize){this.maxSize=maxSize;stack=new int[this.maxSize];}//判断栈满public boolean isFull(){return top==maxSize-1;}//判断栈空public boolean isEmpty(){return top==-1;}//入栈操作public void push(int value){if(isFull()){System.out.println("栈满,不能再添加元素");return;}top++;stack[top]=value;}//出栈操作public int pop(){if(isEmpty()){throw new RuntimeException("栈空");}int value=stack[top];top--;return value;}//遍历栈元素public void list(){if (isEmpty()){System.out.println("栈中没有数据");return;}for(int i=top;i>=0;i--){System.out.printf("stack[%d]=%d\n",i,stack[i]);}}
}

4.测试结果

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=21513:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\1\IdeaProjects\algorithm\out\production\algorithm" cn.zzw.algorithm.Stack.ArrayStackDemo1
表达式1000+102*2-6+2*4=1206
Process finished with exit code 0

七、使用栈实现综合计算器(中缀表达式)相关推荐

  1. 【Java数据结构与算法】第四章 栈实现综合计算器

    第四章 栈实现综合计算器 文章目录 第四章 栈实现综合计算器 一.栈 1.介绍 2.应用场景 3.思路 4.代码实现 二.综合计算器 v1.0 1.思路 2.代码实现 三.前缀.中缀和后缀表达式规则 ...

  2. 【数据结构与算法 6】栈实现综合计算器

    一.栈 栈(stack)又名堆栈,它是一种运算受限的线性表.限定仅在表尾进行插入和删除操作的线性表.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放 ...

  3. 栈的应用_中缀表达式转后缀表达式

    中缀表达式就是我们习惯的表达式比如说1+2*3,后缀表达式是计算机习惯的表达式. 1+2*3转成后缀表达式后:123*+ 中缀转后缀算法: - 遍历中缀表达式中的数字和符号: - 对于符号: - 左括 ...

  4. 栈的应用之中缀表达式转后缀

    前言 栈的一个广泛应用就是讲中缀表达式转换为后缀表达式.所谓中缀表达式就是我们从小到大所接触的:10+3-6/2+4*5 之类的算数表达式.而后缀表达式又称为逆波兰表达式, 它是由波兰逻辑学家J.Lu ...

  5. 数据结构 DAY05 栈的应用之中缀表达式转换

    前缀表达式.中缀表达式和后缀表达式 上一节我们说了计算机是如何计算前缀表达式和后缀表达式的,这一节我们继续说说如何将中缀表达式(给人看的)转换成前缀表达式或后缀表达式. 中缀表达式转换为前缀表达式(注 ...

  6. 万能计算器——中缀表达式转换成后缀表达式(C++实现)【可以计算小数和负数】

    核心代码与思路: int GetExprValue(vector<string> srcVec) //根据后缀表达式求值 {stack<int> temp;char op = ...

  7. 数据结构之中缀表达式实现计算器

    栈还是用的上一篇的数组模拟栈,并在此之上增加了 判断是否是一个运算符的方法 获取运算符的优先级方法 计算结果方法 查看栈顶元素的方法 四个方法,具体代码如下: package com.ebiz.sta ...

  8. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  9. 中缀表达式转后缀表达式——c语言栈实现

    题意 假定运算符集合为{ +.-.*./.(.)},利用栈将输入的中缀表达式转换成等价的后缀表达式,并输出. 输入格式: 输入一个字符串表示的中缀表达式(以"#"结束),其中每个操 ...

最新文章

  1. onsubmit阻止表单提交
  2. php ascii hex编码
  3. B+树(加强版多路平衡查找树)
  4. 485光隔离中继器产品特点及应用领域介绍
  5. SpringCloud系列研究---Eureka服务消费Feign
  6. 如何在Java中生成比特币钱包地址
  7. 软件测试python测试步骤_软件测试员必备基础:3分钟带你入门自动化测试!
  8. BZOJ4311:向量——题解
  9. 数学分析:集合理论----习题
  10. c语言设计一个自动阅卷功能,基于WEB的C语言编程题自动阅卷系统的设计与实现...
  11. STM32开发工具-keil5安装
  12. origin三图合一_利用Origin将多组拟合图放在一张表中的方法
  13. 微博情感分析 mysql_利用500万条微博语料对微博评论进行情感分析
  14. 十行python代码定时给微信好友发送晚安,自动应答--python云舔狗
  15. 宝塔面板ftp空间连接失败解决方案汇总
  16. 计算机组成原理一篇过
  17. macd的python代码同花顺_超牛MACD(代编写程序化交易模型)-同花顺公式 -程序化交易(CXH99.COM)...
  18. DC入门教程(二)——综合的整体流程
  19. M-K趋势检验以及突变检验
  20. 威客---猪八戒http://www.zhubajie.com/

热门文章

  1. 如何访问webService接口
  2. ajax提交数据到后台php接收
  3. Drug Discov. Today | 简要综述GNNs用于分子性质预测
  4. RDKit | 基于RDKit绘制带原子索引的分子
  5. mysql表分区占用存储_MySQL 分区分表应用场景分析和分区中可能遇到的坑点
  6. Galaxy Release (v 21.05),众多核心技术栈变更
  7. B站讲演 | 我为什么要做科普视频?
  8. Nature子刊:微生物系统中的功能与功能冗余
  9. 北京大学吴华君课题组多组学数据分析方向博士后和技术员招聘启示
  10. 扩增子和宏基因组数据分析流程和可视化方案—刘永鑫(南京,2020年11月27日)