栈是一种有序列表,可以使用数组的结构来储存栈的数据内容

思路
 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模拟栈的操作的更多相关文章

  1. java虚拟机栈 相关操作

    针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...

  2. Java 模拟栈结构

    栈和队列: 通常是作为程序猿的工具,用于辅助构思算法.生命周期较短,执行时才被创建 訪问受限.在特定时刻,仅仅有一个数据可被读取或删除 是一种抽象的结构.内部的实现机制.对用户不可见.比方用数组.链表 ...

  3. java模拟键鼠操作

    很久之前百度的,所以忘记了作者,所以仅作为自己的日记纪录在此: package com.robot.test;import java.awt.AWTException;import java.awt. ...

  4. 剑指Offer——Java实现栈和队列的互模拟操作

    剑指Offer--Java实现栈和队列的互模拟操作 栈模拟队列   题目:JAVA实现用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型.   思路:其实就是把队列正常入 ...

  5. 第一回写的用arraylist模拟栈操作

    package hashMap; import java.util.ArrayList; import d.Student; /** * 用ArrayList模拟栈操作 * @author zhuji ...

  6. Java集合List模拟“洗牌”操作

    Collection工具类为操作List集合提供了几个有用的方法: reverse().shuffle().sort().swap().rotate(). 小例子: 使用shuffle(),方法模拟洗 ...

  7. java 16 - 5 LinkedList模拟栈数据结构的集合

    请用LinkedList模拟栈数据结构的集合,并测试 题目的意思是: 你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟. package cn_LinkedList; impo ...

  8. c语言学习,模拟栈操作

    1.stack.c模拟栈操作函数的实现 #include<stdio.h> #include<stdlib.h> ; static char *stack;//数据栈 ;//栈 ...

  9. 浏览器与服务器交互原理以及用java模拟浏览器操作v

    浏览器应用服务器JavaPHPApache * 1,在HTTP的WEB应用中, 应用客户端和服务器之间的状态是通过Session来维持的, 而Session的本质就是Cookie, * 简单的讲,当浏 ...

随机推荐

  1. Typora[MarkDown编辑器]+(PicGo+Github+JsDelivr)[个人图床] ,开启你的高效创作

    使用Typora搭配Picgo开启你的高效创作 0x00 一切都要从MarkDown说起 富文本语言的弊端 平常我们最常用的写作工具,无非是富文本编辑器中的代表--微软家的Office Word.这种 ...

  2. ABP开发框架前后端开发系列---(16)ABP框架升级最新版本的经验总结

    有一小段时间没有持续升级ABP框架了,最近就因应客户的需要,把ABP框架进行全面的更新,由于我们应用的ABP框架,基础部分还是会使用官方的内容,因此升级的时候需要把官方基础ABP的DLL进行全面的更新 ...

  3. (27)ASP.NET Core .NET标准REST库Refit

    1.简介 Refit是一个受到Square的Retrofit库(Java)启发的自动类型安全REST库.通过HttpClient网络请求(POST,GET,PUT,DELETE等封装)把REST AP ...

  4. call 和 apply 和 bind的区别

    有些东西说忘就往,每天记录自己忘记的东西重新学习一遍,挺好 作用:call()和apply()用法都是一样的,改变this的指向问题 区别:接收参数的方式不同, (bind 方法是附加在函数调用后面使 ...

  5. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  6. ggplot2(10) 减少重复性工作

    10.1 简介 灵活性和鲁棒性的敌人是:重复! 10.2 迭代 last_plot()用于获取最后一次绘制或修改的图形. 10.3 绘图模板 gradient_rb <- scale_colou ...

  7. 在vue中实现锚点定位功能

    场景如下: 今天早上看到需求方新提的一个需求,这是一份网上答卷,点击题数要实现滚动到对应题目的位置: 注意点:每题题目的高度是不受控制的,你可以取到想跳转的index:(我再循环题目时做了index+ ...

  8. Natas15 Writeup(sql盲注之布尔盲注)

    Natas15: 源码如下 /* CREATE TABLE `users` ( `username` varchar(64) DEFAULT NULL, `password` varchar(64) ...

  9. 读书笔记——莫提默·J.艾德勒&查尔斯·范多伦(美)《如何阅读一本书》

    第一篇 阅读的层次 第一章 阅读的活力与艺术 阅读的目标:娱乐.获得资讯.增进理解力这本书是为那些想把读书的主要目的当作是增进理解能力的人而写.何谓阅读艺术?这是一个凭借着头脑运作,除了玩味读物中的一 ...

  10. Java基础 - 原码、反码、补码

    目录 机器数 真值 原码 反码 补码 为什么使用原码. 反码. 补码 机器数 所有数字在计算机底层都是以二进制形式存在的.它的表现形式叫做机器数,这个数有正负之分,最高位为符号位.0 表示正数, 1 ...