Go语言-数据结构与算法

news/2024/11/24 5:08:13/
go语言之专业数据结构与算法
20.4 稀疏 sparsearray 数组
20.4.1 先看一个实际的需求
编写的五子棋程序中,有存盘退出和续上盘的功能

稀疏数组的处理方法是 :
1) 记录数组一共有几行几列,有多少个不同的值
2) 思想:把具有不同值的元素的行列及值记录在一个小规模的数组中,从而 缩小程序 的规模
20.4.4 应用实例
1) 使用稀疏数组,来保留类似前面的二维数组 ( 棋盘、地图等等 )
2) 把稀疏数组存盘,并且可以从新恢复原来的二维数组数
3) 整体思路分析

4) 代码实现

package mainimport "fmt"type ValNode struct {row intcol intval int
}func main() {//1. 先创建一个原始数组var chessMap [11][11]intchessMap[1][2] = 1 // 黑子chessMap[2][3] = 2 // 蓝子//2. 输出看看原始的数组for _, v := range chessMap {for _, v2 := range v {fmt.Printf("%d\t", v2)}fmt.Println()}//3. 转成稀疏数组。想-> 算法// 思路//(1). 遍历 chessMap, 如果我们发现有一个元素的值不为 0,创建一个 node 结构体//(2). 将其放入到对应的切片即可var sparseArr []ValNode//标准的一个稀疏数组应该还有一个 记录元素的二维数组的规模(行和列,默认值)//创建一个 ValNode 值结点valNode := ValNode{row: 11,col: 11,val: 0,}sparseArr = append(sparseArr, valNode)for i, v := range chessMap {for j, v2 := range v {if v2 != 0 {//创建一个 ValNode 值结点valNode := ValNode{row: i,col: j,val: v2,}sparseArr = append(sparseArr, valNode)}}}//输出稀疏数组fmt.Println("当前的稀疏数组是:::::")for i, valNode := range sparseArr {fmt.Printf("%d:%d %d %d\n", i, valNode.row, valNode.col, valNode.val)}//将这个稀疏数组,存盘 d:/chessmap.data//如何恢复原始的数组//1. 打开这个 d:/chessmap.data => 恢复原始数组.//2. 这里使用稀疏数组恢复// 先创建一个原始数组var chessMap2 [11][11]int// 遍历 sparseArr [遍历文件每一行]for i, valNode := range sparseArr {if i != 0 {//跳过第一行记录值chessMap2[valNode.row][valNode.col] = valNode.val}}// 看看 chessMap2 是不是恢复fmt.Println("恢复后的原始数据......")for _, v := range chessMap2 {for _, v2 := range v {fmt.Printf("%d\t", v2)}fmt.Println()}
}

PS D:\Workspace\Go\src\projects\gin-demo> go run test.go
0       0       0       0       0       0       0       0       0       0       0
0       0       1       0       0       0       0       0       0       0       0
0       0       0       2       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
当前的稀疏数组是:::::
0:11 11 0 %!d(MISSING)
1:1 2 1 %!d(MISSING)
2:2 3 2 %!d(MISSING)
恢复后的原始数据......
0       0       0       0       0       0       0       0       0       0       0
0       0       1       0       0       0       0       0       0       0       0
0       0       0       2       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0       0       0
对老师的稀疏数组的改进
1) 将构建的稀疏数组,存盘 chessmap.data
2) 在恢复原始二维数组,要求从文件 chessmap.data 读取。
20.5 队列 (queue)
20.5.1 队列的应用场景
20.5.3 数组模拟队列
先完成一个非环形的队列 ( 数组来实现 )

思路分析

 代码实现

package mainimport ("errors""fmt""os"
)//使用一个结构体管理队列
type Queue struct {maxSize intarray   [5]int // 数组=>模拟队列front   int    // 表示指向队列首rear    int    // 表示指向队列的尾部
}//添加数据到队列
func (this *Queue) AddQueue(val int) (err error) {//先判断队列是否已满if this.rear == this.maxSize-1 { //重要重要的提示; rear 是队列尾部(含最后元素)return errors.New("queue full")}this.rear++ // rear 后移this.array[this.rear] = valreturn
}//从队列中取出数据
func (this *Queue) GetQueue() (val int, err error) {//先判断队列是否为空if this.rear == this.front { //队空return -1, errors.New("queue empty")}this.front++val = this.array[this.front]return val, err
}//显示队列, 找到队首,然后到遍历到队尾
func (this *Queue) ShowQueue() {fmt.Println("队列当前的情况是:")//this.front 不包含队首的元素for i := this.front + 1; i <= this.rear; i++ {fmt.Printf("array[%d]=%d\t", i, this.array[i])}fmt.Println()
}//编写一个主函数测试,测试
func main() {//先创建一个队列queue := &Queue{maxSize: 5, front: -1, rear: -1,}var key stringvar val intfor {fmt.Println("1. 输入 add 表示添加数据到队列")fmt.Println("2. 输入 get 表示从队列获取数据")fmt.Println("3. 输入 show 表示显示队列")fmt.Println("4. 输入 exit 表示退出")fmt.Scanln(&key)switch key {case "add":fmt.Println("输入你要入队列数")fmt.Scanln(&val)err := queue.AddQueue(val)if err != nil {fmt.Println(err.Error())} else {fmt.Println("加入队列ok")}case "get":val, err := queue.GetQueue()if err != nil {fmt.Println(err.Error())} else {fmt.Println("从队列中取出了一个数=", val)}case "show":queue.ShowQueue()case "exit":os.Exit(0)}}
}
PS D:\Workspace\Go\src\projects\gin-demo> go run test.go
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
1
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
add
输入你要入队列数
1
加入队列ok
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
get
从队列中取出了一个数= 1
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
4. 输入 exit 表示退出程序
show
队列当前的情况是:1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
队列当前的情况是:
exit status 0xc000013a
PS D:\Workspace\Go\src\projects\gin-demo> go run test.go
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
add
输入你要入队列数
1
加入队列ok
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
get
从队列中取出了一个数= 1
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
show
队列当前的情况是:1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出程序
exit
PS D:\Workspace\Go\src\projects\gin-demo>
对上面代码的小结和说明
1 ) 上面代码实现了基本队列结构,但是 没有有效的利用数组 空间
2 ) 请思考,如何使用数组 实现一个环形的队列
20.5.4 数组模拟环形队列
分析思路 :
1) 什么时候表示队列满 (tail + 1) % maxSize hea d
2) tail == head 表示空
3) 初始化时, tail = 0 head = 0
4) 怎么统计该队列有多少个元素 (tail + maxSize - head ) % maxSize
代码实现
package mainimport ("errors""fmt""os"
)//使用一个结构体管理环形队列
type CircleQueue struct {maxSize int    // 4array   [5]int // 数组head    int    // 指向队列队首 0tail    int    // 指向队尾
}//如队列 AddQueue(push) GetQueue(pop)
//入队列
func (this *CircleQueue) Push(val int) (err error) {if this.IsFull() {return errors.New("queue full")}//分析出 this.tail 在队列尾部,但是包含最后的元素this.array[this.tail] = val // 把值给尾部this.tail = (this.tail + 1) % this.maxSizereturn
}//出队列
func (this *CircleQueue) Pop() (val int, err error) {if this.IsEmpty() {return 0, errors.New("queue empty")}//取出,head 是指向队首,并且含队首元素val = this.array[this.head]this.head = (this.head + 1) % this.maxSizereturn
}//显示队列
func (this *CircleQueue) ListQueue() {fmt.Println("环形队列情况如下:")//取出当前队列有多少个元素size := this.Size()if size == 0 {fmt.Println("队列为空")}//设计一个辅助的变量,指向 headtempHead := this.headfor i := 0; i < size; i++ {fmt.Printf("arr[%d]=%d\t", tempHead, this.array[tempHead])tempHead = (tempHead + 1) % this.maxSize}fmt.Println()
}//判断环形队列为满
func (this *CircleQueue) IsFull() bool {return (this.tail+1)%this.maxSize == this.head
}//判断环形队列是空
func (this *CircleQueue) IsEmpty() bool {return this.tail == this.head
}//取出环形队列有多少个元素
func (this *CircleQueue) Size() int {//这是一个关键的算法.return (this.tail + this.maxSize - this.head) % this.maxSize
}//编写一个主函数测试,测试
func main() {//先创建一个队列queue := &CircleQueue{maxSize: 5, head: 0, tail: 0,}var key stringvar val intfor {fmt.Println("1. 输入 add 表示添加数据到队列")fmt.Println("2. 输入 get 表示从队列获取数据")fmt.Println("3. 输入 show 表示显示队列")fmt.Println("4. 输入 exit 表示退出程序")fmt.Scanln(&key)switch key {case "add":fmt.Println("输入你要入队列数")fmt.Scanln(&val)err := queue.Push(val)if err != nil {fmt.Println(err.Error())} else {fmt.Println("加入队列ok")}case "get":val, err := queue.Pop()if err != nil {fmt.Println(err.Error())} else {fmt.Println("从队列中取出了一个数=", val)}case "show":queue.ListQueue()case "exit":os.Exit(0)}}
}
PS D:\Workspace\Go\src\projects\gin-demo> go run test.go
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
add
输入你要入队列数
1
加入队列ok
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
add
输入你要入队列数
4
加入队列ok
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
add
输入你要入队列数
7
加入队列ok
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
show
环形队列情况如下:
arr[0]=1        arr[1]=4        arr[2]=7
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
get
从队列中取出了一个数= 1
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
get
从队列中取出了一个数= 4
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
get
从队列中取出了一个数= 7
1. 输入 add 表示添加数据到队列
2. 输入 get 表示从队列获取数据
3. 输入 show 表示显示队列
4. 输入 exit 表示退出
exit


http://www.ppmy.cn/news/57184.html

相关文章

[最大距离的最小值]路标设置

[最大距离的最小值]路标设置 题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标…

【测试开发】突破瓶颈必学技能——什么是k8s的核心概念?

目录 Docker 和K8s k8s中的重要概念 Master 节点 Node 节点 集群&#xff08;Cluster&#xff09; 标签&#xff08;Label&#xff09; 命名空间&#xff08;Namespace&#xff09; 容器组&#xff08;Pod&#xff09; 无状态部署&#xff08;Deployment&#xff09;…

封装建立-SMD封装

1. 看规格书&#xff0c;建立需要的焊盘&#xff0c;命名。注意padstack editor保存路径中不能有中文。 2.新建.dra工程&#xff0c;layout/pin 在里面筛选需要的焊盘。 3. 放置焊盘&#xff0c;需要计算精确坐标&#xff0c;allegro里command用x 0 0命令可以定位到原点。 4…

串口信息打印规范(含打印技巧)

1.串口信息打印规范 学习一下串口打印信息的格式&#xff08;清楚明了&#xff0c;调试过程中很重要&#xff09; 日志级别&#xff1a;info&#xff08;初始化&#xff09;、debug&#xff08;运行过程&#xff09;、error&#xff08;报错&#xff09; [日志级别] 文件名 …

网络安全漏洞分析之远程代码执行

介绍 Apache Flume 是一个分布式的&#xff0c;可靠的&#xff0c;并且可用于高效地收集&#xff0c;汇总和移动大量日志数据的软件。它具有基于流数据流的简单而灵活的体系结构。它具有可调的可靠性机制以及许多故障转移和恢复机制&#xff0c;并且具有健壮性和容错性。它使用…

STM32-HAL-SPI-W25Q128FV简单读写测试(2)

文章目录 一、Flash的基本读写操作1.1 向芯片中的某个地址&#xff08;addr:0x02&#xff09;连续写入不定长的数据并读取代码示例读写流程分析函数分析 1.2 向芯片中的某个地址&#xff08;addr:0x00&#xff09;写入一个数值代码示例&#xff1a;读写流程分析 具体的配置接上…

可观测性:你的应用健康吗?

一、需求来源 首先来看一下&#xff0c;整个需求的来源&#xff1a;当把应用迁移到 Kubernetes 之后&#xff0c;要如何去保障应用的健康与稳定呢&#xff1f;其实很简单&#xff0c;可以从两个方面来进行增强&#xff1a; 首先是提高应用的可观测性&#xff1b;第二是提高应…

如何用 GPT-4 帮你写游戏?

你知道的&#xff0c;GPT-4 发布了。 目前你想要用上 GPT-4&#xff0c;主要的渠道是 ChatGPT Plus 。作为交了订阅费的用户&#xff0c;你可以在对话的时候选择模型来使用。 另一种渠道&#xff0c;就是申请官方 API 的排队。我在申请 New Bing Chat 的时候&#xff0c;耐心被…