一、栈

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

二、栈的应用场景

1、子程序的调用

在调往子程序前,会先将下个指令的地址存放到堆栈中,直到子程序执行完后再将地址抛出,以回到原来的程序。

2、处理递归调用

和子程序的调用类似,除了村下个指令的地址外,还要存放参数,区域变量等数据。

3、表达式的转换

中缀表达式转后缀表达式

4、二叉树的遍历

5、图形的深度优先搜索法

三、栈实现综合计算器(中缀表达式)

1、思路分析

  • 通过一个index值(索引),来遍历我们的表达式
  • 如果发现是一个数字直接入数栈
  • 如果发现当前的符号栈是空,就直接入栈
  • 如果发现符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
  • 当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并进行运算。
  • 最后在数栈中只有一个数字,就是表达式的结果。

2、代码实例

(1)ArrayStack工具类

package dataStructure.stack;public class ArrayStack {private int maxSize; // 栈的大小private int[] stack; // 数组,数组模拟栈,数据就放在该数组private int top = -1;// top表示栈顶,初始化为-1//构造器public ArrayStack(int maxSize) {this.maxSize = maxSize;stack = new int[this.maxSize];}//增加一个方法,可以返回当前栈顶的值, 但是不是真正的poppublic int peek() {return stack[top];}//栈满public boolean isFull() {return top == maxSize - 1;}//栈空public boolean isEmpty() {return top == -1;}//入栈-pushpublic void push(int value) {//先判断栈是否满if(isFull()) {System.out.println("栈满");return;}top++;stack[top] = value;}//出栈-pop, 将栈顶的数据返回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]);}}//返回运算符的优先级,优先级是程序员来确定, 优先级使用数字表示//数字越大,则优先级就越高.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 cal(int num1, int num2, int oper) {int res = 0; // res 用于存放计算的结果switch (oper) {case '+':res = num1 + num2;break;case '-':res = num2 - num1;// 注意顺序break;case '*':res = num1 * num2;break;case '/':res = num2 / num1;break;default:break;}return res;}
}

(2)测试类

package dataStructure.stack;public class Calculator {public static void main(String[] args) {//根据前面老师思路,完成表达式的运算String expression = "100/5+2*3-1"; // 25//创建两个栈,数栈,一个符号栈ArrayStack numStack = new ArrayStack(10);ArrayStack operStack = new ArrayStack(10);//定义需要的相关变量int index = 0;//用于扫描int num1 = 0;int num2 = 0;int oper = 0;int res = 0;char ch = ' '; //将每次扫描得到char保存到chString keepNum = ""; //用于拼接 多位数//开始while循环的扫描expressionwhile (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();oper = operStack.pop();res = numStack.cal(num1, num2, oper);//把运算的结果如数栈numStack.push(res);//然后将当前的操作符入符号栈operStack.push(ch);} else {//如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.operStack.push(ch);}} else {//如果为空直接入符号栈..operStack.push(ch); // 1 + 3}} else { //如果是数,则直接入数栈//numStack.push(ch - 48); //? "1+3" '1' => 1//分析思路//1. 当处理多位数时,不能发现是一个数就立即入栈,因为他可能是多位数//2. 在处理数,需要向expression的表达式的index 后再看一位,如果是数就进行扫描,如果是符号才入栈//3. 因此我们需要定义一个变量 字符串,用于拼接//处理多位数keepNum += ch;//如果ch已经是expression的最后一位,就直接入栈if (index == expression.length() - 1) {numStack.push(Integer.parseInt(keepNum));} else {//判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈//注意是看后一位,不是index++if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {//如果后一位是运算符,则入栈 keepNum = "1" 或者 "123"numStack.push(Integer.parseInt(keepNum));//重要的!!!!!!, keepNum清空keepNum = "";}}}//让index + 1, 并判断是否扫描到expression最后.index++;if (index >= expression.length()) {break;}}//当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.while (true) {//如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】if (operStack.isEmpty()) {break;}num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.cal(num1, num2, oper);numStack.push(res);//入栈}//将数栈的最后数,pop出,就是结果int res2 = numStack.pop();System.out.printf("表达式 %s = %d", expression, res2);}
}

3、控制台输出

【数据结构与算法 6】栈实现综合计算器相关推荐

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

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

  2. 数据结构与算法--简单栈实现及其应用

    栈 栈(Stack)是一种限制插入和删除只能在一个位置上进行的表,改位置是表的末端,叫做栈顶top.栈的基本操作有push (进栈)pop(出栈) 栈又叫做LIFO(后进先出)表,下图展示普通push ...

  3. 【万字总结】数据结构与算法简述和CS综合,保姆级一文打包

    数据结构与算法简述和CS综述整理.本文非基础的教程,本文会列出大量学习和参考网站.老惯例,一个文章是一个集大成(本文借助了语音输入(PC 版 讯飞输入法)由此加速码字,但仍保持简洁的文风). 数据结构 ...

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

    使用栈实现综合计算器(中缀表达式) 1.栈的实际需求 请输入一个表达式,计算式:[722-5+1-5+3-3] ,计算出结果 计算机底层是如何运算得到结果的? 注意不是简单的把算式列出运算,因为我们看 ...

  5. 数据结构与算法之栈入门题目

    数据结构与算法之栈题目 目录 用数组实现大小固定的队列和栈 实现一个特殊的栈,在实现栈的基础功能上,再实现返回栈中最小元素的操作 如果仅用栈结构实现队列结构和如何仅用队列结构实现栈结构 1. 用数组实 ...

  6. 数据结构与算法--利用栈实现队列

    利用栈实现队列 上一节中说明了栈的特点 后进先出,我们用数组的方式实现了栈的基本操作api,因此我们对栈的操作是不考虑排序的,每个api的操作基本都是O(1)的世界,因为不考虑顺序,所以找最大,最小值 ...

  7. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  8. 新星计划Day7【数据结构与算法】 栈Part1

    新星计划Day7[数据结构与算法] 栈Part1

  9. 数据结构与算法之-----栈的应用(三)

    [ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己 ...

最新文章

  1. Matlab编程与数据类型 -- 奇数阶魔方矩阵的编程
  2. Microbiome:城环所杨军组-小幅盐度变化改变了城市水库微型真核浮游生物群落的构建过程和网络稳定性...
  3. matlab ezplot绘制隐函数
  4. xmpp 服务器配置 open fire for windows 及 spark 测试
  5. 区块链BaaS云服务(15)复杂美chain33
  6. 网络编程第三讲UDP编写
  7. c++11仔细地将参数传递给线程std::thread
  8. PAT(乙级)1009
  9. Winform控件扩展
  10. Win10无管理员帐户,如何把自己提权为管理员
  11. python中的map()函数详解
  12. 【博士招生】卢森堡大学​SnT(CVI²)研究小组,DeepFake 检测领域
  13. 再学 GDI+[62]: 路径画刷(2) - SetCenterPoint、GetCenterPoint
  14. 关于Block的个人总结
  15. C# Winform代码片段-大二下学期的垃圾代码
  16. 强化学习的数学基础4---Q-Learning进阶
  17. ImgBurn - 简单免费的 CD/DVD 刻录软件
  18. 【数据挖掘算法竞赛】山东省-公积金贷款逾期预测TOP8 baseline523
  19. 完美解决idea Maven Cannot reconnect
  20. Date DateFormat SimpleDateFormat Calendar Joda-Time

热门文章

  1. LZO和MiniLZO编码介绍
  2. 运行项目报错 proxy error: could not proxy request...
  3. 在 iOS 中对接收到的网络数据(NSData)进行文件读写
  4. 【问题思考总结】为什么基础解系中两个自由变量对应两个线性无关的解?
  5. 2019年Linux运维工程师的高薪出路在哪
  6. 数据通信网络基础,华为VRP系统(HCLA-Datacom v1.0华为认证数通笔记2)
  7. python按哪个键运行代码_python运行快捷键是哪个
  8. vue.js动态设置VueComponent高度遇到的问题
  9. 数据库 2.关系模型
  10. 【网络教程】群晖安装甜糖最新教程,手把手教您在Docker中安装官方甜糖