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, * 简单的讲,当浏 ...
随机推荐
- 前端每日实战:131# 视频演示如何用纯 CSS 创作一把剪刀
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/GXyGpZ 可交互视频 此视频是可 ...
- java套打快递单
package org.sq.common.utils; import org.apache.commons.codec.binary.Base64;import org.apache.http.en ...
- Flink系列之状态及检查点
Flink不同于其他实时计算的框架之处是它可以提供针对不同的状态进行编程和计算.本篇文章的主要思路如下,大家可以选择性阅读. 1. Flink的状态分类及不同点. 2. Flink针对不同的状态进行编 ...
- Simulink仿真入门到精通(十一) 模块的封装
当用户编写了自定义的S函数或者使用Simulink标准库中的模块搭建子系统后,可以通过封装为其设计显示外观,追加参数对话框. 封装是构建一个以对话框为接口的交互界面的过程,它将复杂的模块逻辑关系隐藏起 ...
- Vue2.0 【第三季】第2节 computed Option 计算选项
目录 Vue2.0 [第三季]第2节 computed Option 计算选项 第2节 computed Option 计算选项 一.格式化输出结果 二.用计算属性反转数组 Vue2.0 [第三季]第 ...
- 【翻译】.NET 5 Preview 1 发布
.NET 5 Preview 1 发布 去年年底,我们发布了.NET Core 3.0和3.1.这些版本添加了桌面应用程序模型Windows Forms(WinForms)和WPF,ASP.NET B ...
- 问题描述:判断一个整数 n 是否为 2 的幂次方
一.2的幂次方的基本定义 什么样的数为2的幂次方?例如2^0=1,2^1=2,2^2=4……,符合公式2^n(n>=0)的数称为2的幂次方. 如何判断一个数是否为2的幂次方呢?基本思路:把一个数 ...
- span(行级元素)在不定高的div(块级元素)中垂直居中的方法
设置父级元素: align-items: center; display: flex;
- 使用GUI工具Portainer.io管控Docker容器
背景 5年前容器技术扑面而来,如今已经成为面向云原生开发的基础架构,基于微服务的设计需要部署大量容器,同时强调了友好快速的管理容器. 是时候推荐一个轮子Portainer.io:提供GUI界面的容器管 ...
- react / config\webpack.config.js 编译后去掉map 减小体积 shouldUseSourceMap = false
react / config\webpack.config.js 编译后去掉map 减小体积 shouldUseSourceMap = false