数据结构- 栈(实现综合计算器)(一位数计算 扩展到 多位数计算)

思路

在这里插入图片描述

代码(可以看到这里的数字只能是单位数字,那么如何改成可以是多位数呢?!往下看)

package stack;public class Calculator {public static void main(String[] args) {//完成表达式运算String expression = "7+2*6-2*2";//创建两个栈,一个数栈,一个符号栈ArrayStack1 numstack = new ArrayStack1(10);ArrayStack1 operstack = new ArrayStack1(10);//定义需要的相关变量int index = 0; //用于扫描int num1 = 0, num2 = 0;int oper = 0;int res = 0;char ch = ' ';//将每次扫描得到的char保存给ch//开始while循环的扫描expressionwhile(true){//一次得到expression 的每个字符ch = expression.substring(index,index+1).charAt(0);//判断ch是字符还是数字if (operstack.isOper(ch)){//判断符号栈是否为空if (!operstack.isEmpty()){//如果不为空,比较,如果当前操作符小于等于则进行下面操作if (operstack.priority(ch) <= operstack.priority(operstack.peekTop())){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);}}else {//如果是数直接入栈(这里的1是字符'1',要转成数字1,ascll码减48)numstack.push(ch - 48);}//让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);}//打印结果(就是数栈中的最后一个数)System.out.printf("表达式 %s = %d",expression,numstack.pop());}
}class ArrayStack1{private int maxSize; //栈大小private int[] stack;//数组模拟栈,数据放入数组里private int top = -1; //top表示栈顶,初始化为-1//构造器public ArrayStack1(int maxSize) {this.maxSize = maxSize;stack = new int[this.maxSize];}//返回栈顶的值,不出栈public int peekTop(){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;}//出栈public int pop(){if (isEmpty()){//抛出异常throw new RuntimeException("栈空");}int value = stack[top];top--;return value;}//遍历栈(从栈顶开始)public void list(){if (isEmpty()){System.out.println("栈空");}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; //计算结果switch (oper){case '+':res = num1 + num2;break;case '-':res = num2 - num1; //注意顺序break;case '*':res = num1 * num2;break;case '/':res = num2 / num1;break;}return res;}
}

找到是哪个地方有问题?,发现是一个数字就直接入栈了,那么需要在入数栈时,需要向后看,如果是数就拼接并继续扫描,如果是符合才入栈。(那么就需要一个字符串变量用于拼接)

代码

package stack;public class Calculator {public static void main(String[] args) {//完成表达式运算String expression = "71+2*6-2*2";//创建两个栈,一个数栈,一个符号栈ArrayStack1 numstack = new ArrayStack1(10);ArrayStack1 operstack = new ArrayStack1(10);//定义需要的相关变量int index = 0; //用于扫描int num1 = 0, 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()){//如果不为空,比较,如果当前操作符小于等于则进行下面操作if (operstack.priority(ch) <= operstack.priority(operstack.peekTop())){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);}}else {//如果是数直接入栈(这里的1是字符'1',要转成数字1,ascll码减48)//如果有多位数,则需要改进代码,不能直接入栈//思路:// 1.扫描到数字,需要继续向后扫描,如果是数就拼接,继续扫描,直到扫描是字符keepnum += ch;//如果ch是最后一位了则直接入栈if (index == expression.length()-1){numstack.push(Integer.parseInt(keepnum));}else {//判断下一个字符是不是数字,如果是继续扫描if (operstack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {numstack.push(Integer.parseInt(keepnum));//这里一定要清空keepnumkeepnum = "";}}}//让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);}//打印结果(就是数栈中的最后一个数)System.out.printf("表达式 %s = %d",expression,numstack.pop());}
}class ArrayStack1{private int maxSize; //栈大小private int[] stack;//数组模拟栈,数据放入数组里private int top = -1; //top表示栈顶,初始化为-1//构造器public ArrayStack1(int maxSize) {this.maxSize = maxSize;stack = new int[this.maxSize];}//返回栈顶的值,不出栈public int peekTop(){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;}//出栈public int pop(){if (isEmpty()){//抛出异常throw new RuntimeException("栈空");}int value = stack[top];top--;return value;}//遍历栈(从栈顶开始)public void list(){if (isEmpty()){System.out.println("栈空");}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; //计算结果switch (oper){case '+':res = num1 + num2;break;case '-':res = num2 - num1; //注意顺序break;case '*':res = num1 * num2;break;case '/':res = num2 / num1;break;}return res;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构 - 栈(数组模拟栈操作)

数组模拟栈操作 package stack;import java.util.Scanner;public class ArrayStackDemo {public static void main(String[] args) {//测试ArrayStack//创建栈ArrayStack arrayStack new ArrayStack(4);String key "";boolean loop true;Scanner sc new Scanner…

【转】visual studio 2019 (vs) 显示右侧缩略图_缩略图_滚动条

1. 工具 -> 选项 2. 文件编辑器 -> 选项对应的语言(Basic, C#, C/C....) -> 行为 -> 使用垂直滚动条的缩略图模式&#xff08;M&#xff09; 效果&#xff1a;

数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)

栈的三种表达式&#xff1a;前缀、中缀和后缀表达式&#xff0c;后缀也叫逆波兰表达式 前缀&#xff08;波兰表达式&#xff09; 中缀&#xff08;对人来讲很好理解&#xff0c;对于计算机来讲就方便了&#xff0c;一般会把中缀表达式转换成后缀表达式&#xff09; 后缀&#…

数据结构与算法 - 递归回溯(迷宫问题)

递归的概念 简单说就是方法自己调用自己&#xff0c;每次调用时传入不同的变量&#xff0c;递归有助于编程者解决复杂的问题&#xff0c;同时可以让代码简介 递归的调用机制 递归能解决什么问题 递归需要遵守的重要规则 下面用代码来实现一个迷宫问题 主要代码&#xff08;这…

【转】Web Reference和Service Reference的区别

今天因为项目需要使用服务引用&#xff0c;就按之前的经验添加上了&#xff0c;步骤如下&#xff1a; 项目根目录——引用——右键——添加服务引用——高级——添加Web引用——输入接口的URL地址——回车&#xff08;下方出现的就是接口的定义的方法&#xff09;——修改Web引…

数据结构 - 递归 回溯算法(八皇后问题)

游戏地址自己写完了可以根据结果去测试一下。 算法分析 八皇后问题算法思路分析 1&#xff09;第一个皇后先放第一行第一列 2&#xff09;第二个皇后放在第二行第一列、然后判断是否OK&#xff0c; 如果不OK&#xff0c;继续放在.第二列、第三列、依次把所有列都放完&#x…

算法 - 排序算法 的时间复杂度计算

简介 度量一个程序(算法)执行时间的两种方法 1&#xff09;事后统计的方法这种方法可行, 但是有两个问题&#xff1a;一是要想对设计的算法的运行性能进行评测&#xff0c;需要实际运行该程序&#xff1b;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素, 这种方式&a…

【转】Magento2目录结构

目录结构 可以看到,M2的目录挺多的。 我们依次来讲解下, 我这里截取的是github里的源代码,核心代码跟composer和官网下载的源码包的存放路径不一样。 如果是github下载的&#xff0c;那么m2的核心源代码就在app/code/Magento里。 如果是composer安装或者官网下载的源码包&#…

算法 - 排序算法 (算法学习)(冒泡、选择、插入、希尔、快排、归并)

1&#xff09;冒泡排序 1.1 图解演示 2&#xff09;选择排序 import java.text.SimpleDateFormat; import java.util.Date;/*** 选择排序*/ public class chooseSort {public static void selectSort(int[] arr){for (int i 0; i < arr.length; i) {int minIndex i;int m…

【转】1.4 Magento2语法讲解

M2不是一个标准的MVC架构。 这是m2的app/code/Magento/Catalog插件代码。 可以看到&#xff0c;它有Controller,也有Model,也有view. 奇怪的是,在Controller找不到调用模版的代码。 这是因为我们之前讲过,m2的页面都是用xml写的&#xff0c;xml里是由若干个block组成的。block里…

【转】1.5 运行原理剖析

我们不讲底层架构,核心原理,太枯燥&#xff0c;也记不住&#xff0c;没必要。 毕竟不是人人都要当架构师。 我们从M2的模式说起。 理解了他的模式,就知道了他的原理。 M2有3种模式, 默认模式(default)开发模式(developer)生产模式(production) 默认模式 安装完成后&#xf…

SparkStreaming简介 - 与第一个Spark实时计算程序,使用netcat来写数据 - wordcount

官方文档 Spark Streaming 火花流是spark API的扩展&#xff0c;它支持可伸缩、高吞吐量、容错的实时数据流处理。 数据可以从多种来源(如Kafka、Flume、Kinesis或tcp套接字)中摄取&#xff0c;并且可以使用用高级函数表示的复杂算法进行处理&#xff0c;例如map, reduce, jo…

【转】老邹说Magento的前世今生

文章目录[隐藏] Magento Commerce的历史Magento 2版本历史Magento电子商务的特点和功能Magento市场Magento认证Magento事件为什么Magento统治电子商务领域 想要深入了解magento&#xff0c;我们有必要回顾一下Magento的前世今生&#xff0c;看它是如何一步步成长起来的。 为什…

【转】Magento2 安装系列一 虚拟机、CentOS7 安装

前言 最近打算在Windows10安装最新的magento2.3&#xff0c;由于mg2.3对Windows支持不太友好&#xff0c;所以就打算在Windows10安装虚拟机&#xff0c;虚拟机安装CentOS7版本的Linux&#xff0c;Linux安装Lnmp环境&#xff0c;最终安装Magento2.3.虚拟机选择与安装 我这边打算…

SparkStreaming -Kafka数据源

SparkStreaming处理kafka作为数据源 所以我们要创建的是kafka的Dstream&#xff0c;那么就要使用到KafkaUtils下的createStream&#xff0c;先来看一下ctrl点进去查看&#xff0c;然后来写参数 package date_10_16_SparkStreamingimport org.apache.spark.SparkConf import or…

SparkStreaming - 无状态与有状态 updataStateByKey

无状态与有状态 简单来说&#xff0c;无状态就是每个采集周期分别采集&#xff0c;并不会把前面的采集周期的数据一起计算 有状态就是&#xff1a;把前面采集周期的也算进来&#xff0c; 比如wordcount&#xff0c;无状态统计的就是每个采集周期内的个数&#xff0c;有状态的…

flink(一个流处理,一个批处理)

流处理&#xff0c;这里用netcat来完成 package com.smalltiger.flinkWCimport org.apache.flink.api.java.utils.ParameterTool import org.apache.flink.streaming.api.scala._/*** Created by smalltiger on 2019/11/6.* flink基于流处理的一个WordCount统计*/ object Stre…

volatile学习(可见性,不保证原子性,禁止指令重排(双端检索机制))

volatile是java虚拟机提供的轻量级的同步机制&#xff1a; 1.保证可见性&#xff1a;线程之间可见性(及时通知) 2.不保证原子性 3.禁止指令重排 先了解一下jvm同步 由于JVM运行程序的实体是线程&#xff0c;而每个线程创建时JVM都会为其创建一个工作内存&#xff08;或者称为…

CAS(比较并交换)学习CAS实现原子性+volatile实现可见性,cas与synchronized比较的优缺点

1、CAS底层原理&#xff1f; 自旋锁(cas思想)unsafe类&#xff0c;保证原子性靠的是unsafe类 1.首先可以看到&#xff1a; atomicInteger.getAndIncrement();getAndIncrement()的底层是 public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset,…

cas引出的ABA问题?如何解决?- 理解原子引用、时间戳(版本号)原子引用

ABA问题&#xff1a; 假如有两个线程1&#xff0c;2&#xff1b; cas下&#xff1a;1.线程取值完等待&#xff0c;2线程取值并把A改成B&#xff0c;有把B改成A&#xff0c;这是1线程执行会任务A还是原来的A没有发生改变&#xff0c;如果不在乎中间结果&#xff0c;只看收尾&am…