java模拟栈的操作
栈是一种有序列表,可以使用数组的结构来储存栈的数据内容
思路
1. 创建一个栈类StackArray
2. 定义一个top来模拟栈顶,初始化为-1
3. 入栈: 当有数据加入到栈的时候 top++ stack[top] = data
4. 出栈 int value = stack[top]; top--, return value
代码实现
//定义一个类来表示栈
class ArrayStack{
private int maxSize; //栈的大小
private int[] stack; //数组模拟栈 数据放在数组中
private int top = -1; //top 表示栈顶 //构造器
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
} //栈满 当栈顶和栈容量相等时 栈满
public boolean isFull(){
return top == maxSize - 1;
} //判断栈空
public boolean isEmpty(){
return top == -1;
} //入栈 push
public 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]);
}
} }
通过main方法调用自定义的栈类来模拟栈的操作
public class StackArrayDemo {
public static void main(String[] args) {
//测试ArrayStack
//创建一个ArrayStack对象
ArrayStack stack = new ArrayStack(4);
String key = "";
boolean loop = true; //控制是否退出菜单
Scanner scanner = new Scanner(System.in);
while (loop){
System.out.println("show: 表示显示栈");
System.out.println("exit: 退出程序");
System.out.println("push: 表示添加数据到栈");
System.out.println("pop: 表示从栈取出数据");
System.out.println("请输入你的选择: ");
key = scanner.next();
switch (key){
case "show":
stack.list();
break;
case "push":
System.out.println("请输入一个数: ");
int value = scanner.nextInt();
stack.push(value);
break;
case "pop":
try{
int result = stack.pop();
System.out.printf("取出的数据为:%d\n", result);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case "exit":
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
根据上边的内容 来模拟一下用栈实现的计算表达式的功能
思路
通过一个index(索引) 来遍历我们的表达式
如果我们发现是一个数字 就直接入数栈
如果扫描到的是一个符号 就分如下情况
1.如果当前符号栈为空, 就直接入栈
2.如果符号栈有操作符 就进行比较 如果当前操作符的优先级 小于或等于栈中的操作符
就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将得到的结果入数栈
再把当前的符号入符号栈,
3.如果当前符号的优先级大于栈中的操作符,直接入栈
扫描完毕后 就顺序地冲数栈和符号栈中pop出响应的数和符号 并运行
最后在数栈中只有一个数字就是表达式的结果 参考上边的ArrayStack类 拓展一个ArrayStack2 类 并对功能进行增强
//定义一个类来表示栈 对ArrayStack进行扩展
class ArrayStack2{
private int maxSize; //栈的大小
private int[] stack; //数组模拟栈 数据放在数组中
private int top = -1; //top 表示栈顶 //构造器
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
} //栈满 当栈顶和栈容量相等时 栈满
public boolean isFull(){
return top == maxSize - 1;
} //判断栈空
public boolean isEmpty(){
return top == -1;
} //入栈 push
public 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 oper, int num1, int num2){
int result = 0; // 用于存放计算的结果
switch (oper){
case '+':
result = num1 + num2;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num2 * num1;
break;
case '/':
result = num2 / num1;
break;
default:
break;
} return result;
} //返回栈顶的值 不Pop
public int peek(){
return stack[top];
} }
调用主方法 进行案例的具体实现
public class StackCalculate {
public static void main(String[] args) {
//完成表达式的运算
String expression = "500+7*2-8";
//创建两个栈 一个数栈一个符号栈
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
//定义扫描的索引
int index = 0;
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
//将每次扫描的的char保存到ch中
char ch = ' ';
//用于拼接多位数
String keepNum = "";
//循环扫描表达式
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();
oper = operStack.pop();
//运算
res = numStack.cal(oper,num1, num2);
//将运算结果压入数栈
numStack.push(res);
//将当前运算符压入符号栈
operStack.push(ch);
}else {
operStack.push(ch);
}
}else {
//为空 直接入栈、
operStack.push(ch);
}
}else {
//如果ch是数字 直接入数栈
// numStack.push(ch - 48); // ASCII码转换成int
//当处理多位数时 有可能是多位数 因此 需要定义一个字符串变量 用于拼接
keepNum += ch;
//如果ch已经到expression的最后一位了直接入栈
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));
//!!重要的 清空keepNum
keepNum = "";
}
}
//index ++ 判断是否扫描到表达式最后的位置
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(oper,num1, num2);
numStack.push(res);
}
//将最后的计算结果pop出
int finalRes = numStack.pop();
System.out.printf("表达式%s = %d", expression, finalRes);
}
}
java模拟栈的操作的更多相关文章
- java虚拟机栈 相关操作
针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...
- Java 模拟栈结构
栈和队列: 通常是作为程序猿的工具,用于辅助构思算法.生命周期较短,执行时才被创建 訪问受限.在特定时刻,仅仅有一个数据可被读取或删除 是一种抽象的结构.内部的实现机制.对用户不可见.比方用数组.链表 ...
- java模拟键鼠操作
很久之前百度的,所以忘记了作者,所以仅作为自己的日记纪录在此: package com.robot.test;import java.awt.AWTException;import java.awt. ...
- 剑指Offer——Java实现栈和队列的互模拟操作
剑指Offer--Java实现栈和队列的互模拟操作 栈模拟队列 题目:JAVA实现用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 思路:其实就是把队列正常入 ...
- 第一回写的用arraylist模拟栈操作
package hashMap; import java.util.ArrayList; import d.Student; /** * 用ArrayList模拟栈操作 * @author zhuji ...
- Java集合List模拟“洗牌”操作
Collection工具类为操作List集合提供了几个有用的方法: reverse().shuffle().sort().swap().rotate(). 小例子: 使用shuffle(),方法模拟洗 ...
- java 16 - 5 LinkedList模拟栈数据结构的集合
请用LinkedList模拟栈数据结构的集合,并测试 题目的意思是: 你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟. package cn_LinkedList; impo ...
- c语言学习,模拟栈操作
1.stack.c模拟栈操作函数的实现 #include<stdio.h> #include<stdlib.h> ; static char *stack;//数据栈 ;//栈 ...
- 浏览器与服务器交互原理以及用java模拟浏览器操作v
浏览器应用服务器JavaPHPApache * 1,在HTTP的WEB应用中, 应用客户端和服务器之间的状态是通过Session来维持的, 而Session的本质就是Cookie, * 简单的讲,当浏 ...
随机推荐
- HTML中的meta标签常用属性及其作用总结
文章同步到github 以前没怎么太注意过meta标签的作用,只是简单了解一些常用属性,现在结合个人了解的进行记录与总结: 元数据 首先需要了解一下元数据(metadata)元素的概念,用来构建HTM ...
- [Tensorflow-CPU完整安装过程-Win10]新手各种踩过的坑
流程介绍:先安装Anaconda(不同Python版本对于Anaconda不同!!见图),然后就是在Anaconda Prompt里面安装Tensorflow即可. 环境介绍:Anaconda3-4. ...
- 关于Spring和SpringMVC的总结
1.Spring中AOP的应用场景.AOP原理.好处? 答:AOP:Aspect Oriented Programming面向切面编程:用来封装横切关注点,具体可以在下面场景中使用: Authenti ...
- redis 出现(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details
如果在ubuntu安装的redis含端口使用,但是某些时候常常出现 (error) MISCONF Redis is configured to save RDB snapshots, but is ...
- mybatis进阶案例之多表查询
mybatis进阶案例之多表查询 一.mybatis中表之间的关系 在数据库中,实体型之间的关系主要有如下几种: 1.一对一 如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之 ...
- 基于 HTML + WebGL 结合 23D 的疫情地图实时大屏 PC 版
前言 2019年12月以来,湖北省武汉市陆续发现了多例肺炎病例,现已证实为一种新型冠状病毒感染引起的急性呼吸道传染病并蔓延全国,肺炎疫情牵动人心,人们每天起来第一件事变成了关注疫情进展,期望这场天灾早 ...
- win10 安装虚拟机提示 主IP地址显示网络信息不可用
问题:在虚拟机详情下面显示 主ip地址:网络信息不可用 解决办法: 先root用户[root@dfhf~]#cd ..[root@dfhf/]#cd /etc/sysconfig/network-sc ...
- Python只有文件不存在才能写文件
当我们在Python里面写文件时,我们常用的模式为 w模式,这种模式下,如果文件不存在,就会生成文件:如果文件已经存在,就会直接覆盖. 有时候,如果文件已经存在,直接覆盖文件可能会导致重要数据丢失.你 ...
- python基础学习day4
列表的初识 why:int bool str str: 存储少量的数据. str:切片还是对其进行任何操作,获取的内容全都是str类型.存储的数据单一. what:list list = [66, ' ...
- XiaoQi.Study项目(二)
一.EF Core 使用的补充 1) 创建 接口 IEFCoreService 2) 实现 接口 EFCoreService 3) 在Startup.cs 中注册 ef 服务 并在控制器中注入使用 ...