Java玩转《啊哈算法》解密QQ号之队列

行有不得,反求诸己

文章目录

  • 开头
  • 代码地址
  • 引子
    • 案例
    • 分析
    • 代码
  • 队列
    • 封装
    • 升级
    • 演示

开头

各位好!本人在看《啊哈算法》,写的确实不错。

但略微遗憾的是,书籍示例代码是c语言,不是本人常用的Java。

那就弥补遗憾,说干就干,把这本书的示例语言用java过一遍, 顺便附上自己的一些理解!

于是就有了本篇博客,本篇博客主要是讲常见数据结构的一种:队列。

在这里插入图片描述

来不及买纸质书但又想尽快感受算法魅力的童鞋也甭担心,电子版的下载链接已经放到下方了,可尽情下载。

链接:https://pan.baidu.com/s/1imxiElcCorw2F-HJEnB-PA?pwd=jmgs
提取码:jmgs

在这里插入图片描述

代码地址

本文代码已开源:

git clone https://gitee.com/guqueyue/my-blog-demo.git

请切换到gitee分支,

然后查看aHaAlgorithm模块下的src/main/java/com/guqueyue/aHaAlgorithm/chapter_2_StackAndChainTable即可!

引子

案例

在书中,作者直接给出了一个案例来引出队列这个概念:

新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问QQ号,小哈当然不会直接告诉小哼啦,原因嘛你懂的。所以小哈给了小哼一串加密过的数字,同时小哈也告诉了小哼解密规则。

规则是这样的:首先将第1个数删除,紧接着将第2个数放到这串数的末尾,再将第3个数删除并将第4个数放到这串数的末尾,再将第5个数删除……直到剩下最后一个数,将最后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一起就是小哈的QQ啦

现在你来帮帮小哼吧。小哈给小哼加密过的一串数是“6 3 1 7 5 8 9 2 4”。

在这里插入图片描述

分析

那么,如何通过抽象化的编程来解决这个具体化的问题呢?

其实很简单,只需要三步即可!!!

  1. 首先,我们需要声明一个数组用来存储QQ号,这里其实我们就是用数组来模拟队列。
  2. 其次,我们要运用双指针的思想,声明一个头指针和一个尾指针。头指针指向队列头部,尾指针指向队列尾部后一位。
  3. 然后,我们只需要一直执行第一个元素出队并打印,下一个元素出队并入队的操作,直至两个指针相遇即队列为空便可。

下面是整体的流程图:
在这里插入图片描述

代码

根据上文的分析,我们不难编写出以下代码:

package com.guqueyue.aHaAlgorithm.chapter_2_StackAndChainTable;/*** @Author: guqueyue* @Description: 解密QQ - 本质是以数组模拟队列* @Date: 2024/1/11**/
public class DecodeQQ {public static void main(String[] args) {// 加密过的qq号int[] qq = {6, 3, 1, 7, 5, 8, 9, 2, 4};// 创建一个长度为101的队列int[] queue = new int[101];// 初始化队列:头指针head指向队列头部,尾指针tail指向队列尾部后一位int head = 0, tail = 0;// 初始化队列:tail为尾指针,指向队列尾部后一位for (int num : qq) {queue[tail++] = num;}// 破解qq号while (head < tail) { // 队列不能为空// 打印队首并出队System.out.print(queue[head++] + " ");// 将队首的数字放到队尾queue[tail++] = queue[head++];}System.out.println();}
}

运行代码,可得:
在这里插入图片描述

队列

在上文中,我们看似用的是 数组双指针的方法,其实我们运用的是队列的思想。

当然,用链表也能实现栈,这里我们就不讲了。

队列,顾名思义,就是跟排队一样,先到的人先买票,后到的人后买票
在这里插入图片描述

也就是说,队列只有两种操作:

  1. 队首的人出队
  2. 新来的人入队

这里面有一个非常重要的核心概念 - FIFO(First In First Out) - 先进先出

与之对应的我们后面要讲到的栈,它是先进后出。队列和栈可以说是算法里面比较核心的两种数据结构了,不容小视。

封装

为了方便使用,减少重复性代码,我们可以专门封装一个队列类:

package com.guqueyue.aHaAlgorithm.entity;/*** @Author: guqueyue* @Description: 队列类 - 通过数组实现* @Date: 2024/1/11**/
public class Queue {public int[] data = new int[1001]; // 数组,用来储存内容public int head; // 队首public int tail; // 队尾@Overridepublic String toString() {String str = "";int head = this.head, tail = this.tail;while (head < tail) {str += data[head++] + " ";}str += "\n";return str;}
}

这里主要有三个核心:

  1. 用来存储元素的数组
  2. 队首指针
  3. 队尾指针
    在这里插入图片描述
    然后,跟原书不同的是:为了方便输出队列元素,我们还重写了队列类的toString()方法。

这样的话,我们使用队列,只需要创建一个队列对象。

出队只需要将队首指针+1,入队只需要根据队尾指针进行赋值操作,然后再将队尾指针+1即可。

如下代码,我们创建一个队列,将元素3入队,再出队为:

   Queue queue = new Queue(); // 创建队列queue.data[queue.tail++] = 3; // 将3入队queue.head++; // 再将3出队

升级

我们运用队列封装类,可以给上文的案例代码进行如下改装:

package com.guqueyue.aHaAlgorithm.chapter_2_StackAndChainTable;import com.guqueyue.aHaAlgorithm.entity.Queue;import java.util.Scanner;/*** @Author: guqueyue* @Description: 队列演示* @Date: 2024/1/11**/
public class QueueTest {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("你要输入几个数?:");int n = scanner.nextInt();// 初始化队列Queue queue = new Queue();System.out.printf("清输入%d个数,中间用空格隔开,再回车:", n);for (int i = 0; i < n; i++) {queue.data[queue.tail++] = scanner.nextInt();}System.out.print("解密后的qq号为:");while (queue.head < queue.tail) { // 队列不为空,则循环// 打印队首并出队System.out.print(queue.data[queue.head++] + " ");// 将队首移到队尾queue.data[queue.tail++] = queue.data[queue.head++];}System.out.println(); // 换行}
}

演示

运行代码,控制台输入,可得:

在这里插入图片描述

最后,放一段作者的吐槽:

队列的起源已经无法追溯。在还没有数字计算机之前,数学应用中就已经有对队列的记载了。
我们生活中队列的例子也比比皆是,比如排队买票,又或者吃饭时候用来排队等候的叫号机,又或者拨打银行客服选择人工服务时,每次都会被提示“客服人员正忙,请耐心等待”,因为客服人员太少了,拨打电话的客户需要按照打进的时间顺序进行等候等等。
这里表扬一下肯德基的宅急送,没有做广告的嫌疑啊,每次一打就通,基本不需要等待。
但是我每次打银行的客服(具体是哪家银行就不点名了)基本都要等待很长时间,总是告诉我“正在转接,请稍候”,嘟嘟嘟三声
后就变成“客服正忙,请耐心等待!”然后就给我放很难听的曲子。看来钱在谁那里谁就是老大啊……

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

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

相关文章

分布式搜索引擎_学习笔记_3

分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合&#xff08;aggregations&#xff09;**可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售…

matlab中的图窗属性和坐标轴的属性

图窗的Position和Outerposition Position 指定窗口的尺寸和窗口在屏幕中的位置。 Outerposition 指定窗口外轮廓的大小和位置。 两者都是用一个4维向量来定义&#xff0c;格式为[左 底 宽 高]。 可通过set函数修改Position和Outerposition&#xff0c;如下&#xff1a;在屏幕左…

color - 让你的输出带点颜色

color color 是一个可以让你输出带颜色文本的库。 安装 go get github.com/fatih/color示例 输出到控制台 // 这会直接输出到控制台 color.Cyan("Prints text in cyan.")// 每个调用末尾会自动加上换行 color.Blue("Prints %s in blue.", "text&…

VMware vCenter告警:vSphere UI运行状况警报

vSphere UI运行状况警报 不会详细显示告警的具体内容&#xff0c;需要我们自己进一步确认告警原因。 vSphere UI运行状况警报是一种监控工具&#xff0c;用于检测vSphere环境中的潜在问题。当警报触发时&#xff0c;通常表示系统遇到了影响性能或可用性的问题。解决vSphere UI…

软件测试之软件缺陷管理

什么是软件缺陷 标准的定义&#xff1a;从产品内部看&#xff0c;缺陷是软件产品开发或维护过程中存在的错误、毛病等各种问题&#xff1b;从产品外部看&#xff0c;缺陷是系统所需要实现的某种功能的失效或违背 软件缺陷的生命周期 一个缺陷的正常生命周期是 新建&#xff…

如何分辨坏信息?

每当有社会热点&#xff0c;大家也许都会遇到一个困扰&#xff1a; 铺天盖地的信息&#xff0c;实在是太多了。究竟哪一些值得信任&#xff0c;哪些不值得信任&#xff1f;哪些可以接受&#xff0c;哪些最好保持怀疑&#xff1f; 我想用这篇文章&#xff0c;彻底把这个问题讲清…

CSS定位

定位的组成&#xff1a; 这个属性只有当position属性设置为absolute、fixed、relative时才有效。而且在position属性取值不同时&#xff0c;它们的含义也不同。left和right属性值除了可以设置为绝对的像素数外&#xff0c;还可以设置百分数。 定位模式&#xff1a; 静态定位st…

易语言系列学习1

通过本文章你会学习到 如果 如果真 获取编辑框内容 关闭本程序 监听按键让它等价于点击某个按钮 运算&#xff1a;或 且 非&#xff08;注意中间要有一个空格&#xff0c;否则会报错&#xff09; 效果 .版本 2.程序集 窗口程序集_启动窗口.子程序 _按钮2_被单击. 如果真 (编…

【项目实践02】【优先级阻塞队列】

文章目录 一、前言二、项目背景三、实现方案四、思路延伸1. 优先级队列1.1 concurrent 包下的 PriorityBlockingQueue1.2 Redisson 的优先级阻塞队列 2. jvisualvm 远程连接3. Jstack 高 CPU 排查 五、参考内容 一、前言 本系列用来记录一些在实际项目中的小东西&#xff0c;并…

qemu 抓取linux kernel vmcore

一、背景 在qemu调试linux kernel时 有时我们会遇到dump 情况&#xff0c;这时可以通过gdb 方式连接分析dump&#xff0c; 但实际中我们用得更多的是离线dump 分析&#xff0c;分析的文件通常是vmcore&#xff08;linux kernel panic 生成的coredump文件&#xff09;或者ramdu…

【多个SpringBoot模块项目如何变成聚合项目】

【前言】 项目虽然是Eureka、OpenFeign 进行服务注册和服务调用&#xff0c;但是每个模块都是一个单独的SpringBoot&#xff0c;启动每个模块都需要单独启动一个idea,觉得这个过于繁琐&#xff0c;现在想把项目变成一个聚合项目&#xff0c;只需要启动一个idea即可。 【过程】…

【数据结构 08】红黑树

一、概述 红黑树&#xff0c;是一种二叉搜索树&#xff0c;每一个节点上有一个存储位表示节点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长上两倍&#xff0c;因而是接进…

UGUI中Text和TextMeshPro实现图文混排方式

一些项目中实现图文混排是自定义一个脚本去继承Text类&#xff0c;然后文本中用富文本的方式进行图片和超链接的定义&#xff0c;在代码中用正则表达式匹配的方式把文本中图片和超链接给替换&#xff0c;如下&#xff1a; TextMeshPro实现是生成SpriteAsset进行图文混排的&…

YOLOv8-Segment C++

YOLOv8-Segment C https://github.com/triple-Mu/YOLOv8-TensorRT 这张图像是运行yolov8-seg程序得到的结果图&#xff0c;首先是检测到了person、bus及skateboard(这个是检测错误&#xff0c;将鞋及其影子检测成了滑板&#xff0c;偶尔存在错误也属正常)&#xff0c;然后用方…

go并发编程-runtime、Channel与Goroutine

1. runtime包 1.1.1. runtime.Gosched() 让出CPU时间片&#xff0c;重新等待安排任务(大概意思就是本来计划的好好的周末出去烧烤&#xff0c;但是你妈让你去相亲,两种情况第一就是你相亲速度非常快&#xff0c;见面就黄不耽误你继续烧烤&#xff0c;第二种情况就是你相亲速度…

电脑用的视频编辑软件有哪些 视频剪辑软件排行榜 视频剪辑软件推荐 视频剪辑培训学习 视频剪辑制作自学 电脑视频剪辑需要什么配置

电脑视频剪辑软件这么多&#xff0c;到底哪些比较好用&#xff1f;下面就让我们以十大电脑视频剪辑软件排行榜来细数好用的软件。另外&#xff0c;电脑视频剪辑需要什么配置&#xff1f;本文也会给大家从内存、CPU等参数上介绍&#xff0c;并推荐好用的电脑设备。 一、十大电脑…

Javaweb之SpringBootWeb案例之配置文件的详细解析

4. 配置文件 员工管理的增删改查功能我们已开发完成&#xff0c;但在我们所开发的程序中还一些小问题&#xff0c;下面我们就来分析一下当前案例中存在的问题以及如何优化解决。 4.1 参数配置化 在我们之前编写的程序中进行文件上传时&#xff0c;需要调用AliOSSUtils工具类&…

基于springboot+vue的校园赛事资讯网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【Python笔记-设计模式】建造者模式

一、说明 又称生成器&#xff0c;是一种创建型设计模式&#xff0c;使其能够分步骤创建复杂对象。允许使用相同的创建代码生成不同类型和形式的对象。 (一) 解决问题 对象的创建问题&#xff1a;当一个对象的构建过程复杂&#xff0c;且部分构建过程相互独立时&#xff0c;可…

leetcode-704.二分查找

题目 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9输出: 4 解释: 9 …