【数据结构(二)】稀疏 sparsearray 数组(1)
文章目录
- 1. 稀疏数组的应用场景
- 1.1. 一个实际的需求
- 1.2. 基本介绍
- 2. 稀疏数组转换的思路分析
- 3. 稀疏数组的代码实现
- 3.1. 二维数组转稀疏数组
- 3.2. 稀疏数组转二维数组
- 4. 课后练习
1. 稀疏数组的应用场景
1.1. 一个实际的需求
问题:
编写的五子棋程序中,有存盘退出和续上盘的功能。
分析问题:
因为该二维数组的很多值是默认值 0, 因此记录了很多没有意义的数据 -> 稀疏数组
1.2. 基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法:
①记录数组一共有几行几列,有多少个不同的值
②把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
上图右表中:
第[0]行表示:数组大小是6×7,共有8个不为0的值;下面每一行都代表不为0的数值所在的行列数,[1]~[8]共有8个。
2. 稀疏数组转换的思路分析
1. 步骤
①使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
②把稀疏数组存盘,并且可以从新恢复原来的二维数组数
2. 整体思路分析
二维数组 转 稀疏数组的思路
- 遍历 原始的二维数组,得到有效数据的个数 sum(上图为:2)
- 根据sum 就可以创建 稀疏数组 sparseArr int[sum + 1] [3](上图为:[3][3])
- 将二维数组的有效数据数据存入到 稀疏数组
稀疏数组 转 原始的二维数组的思路
- 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]
- 在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可。
3. 稀疏数组的代码实现
3.1. 二维数组转稀疏数组
package sparsearray;public class SparseArray {public static void main(String[] args) {//创建一个原始的二维数组11×11//0表示没有棋子,1表示黑子,2表示蓝子int chessArr1[][] = new int[11][11];chessArr1[1][2] = 1;chessArr1[2][3] = 2;//可以在后面继续加棋子//输出原始的二维数组for(int[] row : chessArr1){for(int data : row){System.out.printf("%d\t", data);}System.out.println();}//将二维数组 转 稀疏数组//1.先遍历二维数组,得到非0数据的个数System.out.println("数组的长度为:" + chessArr1.length);int sum = 0;for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){sum ++;}}}System.out.println("sum=" + sum);//2. 创建对应的稀疏数组int sparseArr[][] = new int[sum + 1][3];//给稀疏数组赋值sparseArr[0][0] = 11;sparseArr[0][1] = 11;sparseArr[0][2] = sum;//遍历二维数组,将非0的值存放到sparseArr中int count = 0; //count 用于记录是第几个非0数据for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){count++;sparseArr[count][0] = i;sparseArr[count][1] = j;sparseArr[count][2] = chessArr1[i][j];}}}//输出稀疏数组的形式System.err.println();System.out.println("得到的稀疏数组为~~~");for(int i = 0; i < sparseArr.length; i++){System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);}System.out.println();}
}
运行结果:
如果在棋盘上继续加子,如在第5行第6列加一个黑子chessArr1[4][5] = 1;
代码:
package sparsearray;public class SparseArray {public static void main(String[] args) {//创建一个原始的二维数组11×11//0表示没有棋子,1表示黑子,2表示蓝子int chessArr1[][] = new int[11][11];chessArr1[1][2] = 1;chessArr1[2][3] = 2;chessArr1[4][5] = 1;//输出原始的二维数组for(int[] row : chessArr1){for(int data : row){System.out.printf("%d\t", data);}System.out.println();}//将二维数组 转 稀疏数组//1.先遍历二维数组,得到非0数据的个数System.out.println("数组的长度为:" + chessArr1.length);int sum = 0;for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){sum ++;}}}System.out.println("sum=" + sum);//2. 创建对应的稀疏数组int sparseArr[][] = new int[sum + 1][3];//给稀疏数组赋值sparseArr[0][0] = 11;sparseArr[0][1] = 11;sparseArr[0][2] = sum;//遍历二维数组,将非0的值存放到sparseArr中int count = 0; //count 用于记录是第几个非0数据for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){count++;sparseArr[count][0] = i;sparseArr[count][1] = j;sparseArr[count][2] = chessArr1[i][j];}}}//输出稀疏数组的形式System.err.println();System.out.println("得到的稀疏数组为~~~");for(int i = 0; i < sparseArr.length; i++){System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);}System.out.println();}
}
运行结果:
3.2. 稀疏数组转二维数组
package sparsearray;public class SparseArray {public static void main(String[] args) {//创建一个原始的二维数组11×11//0表示没有棋子,1表示黑子,2表示蓝子int chessArr1[][] = new int[11][11];chessArr1[1][2] = 1;chessArr1[2][3] = 2;chessArr1[4][5] = 1;//输出原始的二维数组for(int[] row : chessArr1){for(int data : row){System.out.printf("%d\t", data);}System.out.println();}//将二维数组 转 稀疏数组//1.先遍历二维数组,得到非0数据的个数System.out.println("数组的长度为:" + chessArr1.length);int sum = 0;for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){sum ++;}}}System.out.println("sum=" + sum);//2. 创建对应的稀疏数组int sparseArr[][] = new int[sum + 1][3];//给稀疏数组赋值sparseArr[0][0] = 11;sparseArr[0][1] = 11;sparseArr[0][2] = sum;//遍历二维数组,将非0的值存放到sparseArr中int count = 0; //count 用于记录是第几个非0数据for(int i = 0; i < chessArr1.length; i++){for(int j = 0; j < chessArr1.length; j++){if(chessArr1[i][j] != 0){count++;sparseArr[count][0] = i;sparseArr[count][1] = j;sparseArr[count][2] = chessArr1[i][j];}}}//输出稀疏数组的形式System.err.println();System.out.println("得到的稀疏数组为~~~");for(int i = 0; i < sparseArr.length; i++){System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);}System.out.println();//将稀疏数组-->恢复成 原始的二维数组/*** 1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]* 2. 在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可。*///1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];//2. 在读取稀疏数组后几行的数据(从第二行开始),并赋给 原始的二维数组 即可。for(int i = 1; i < sparseArr.length; i++){chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];}//输出恢复后的二维数组System.err.println();System.out.println("恢复后的二维数组");for(int[] row : chessArr2){for(int data : row){System.out.printf("%d\t", data);}System.out.println();}}
}
运行结果:
4. 课后练习
要求:
(1)在前面的基础上,将稀疏数组保存到磁盘上,比如 map.data
(2)恢复原来的数组时,读取 map.data 进行恢复
相关文章:

【数据结构(二)】稀疏 sparsearray 数组(1)
文章目录 1. 稀疏数组的应用场景1.1. 一个实际的需求1.2. 基本介绍 2. 稀疏数组转换的思路分析3. 稀疏数组的代码实现3.1. 二维数组转稀疏数组3.2. 稀疏数组转二维数组 4. 课后练习 1. 稀疏数组的应用场景 1.1. 一个实际的需求 问题: 编写的五子棋程序中&…...

MySQL的执行器是怎么工作的
作为优化器后的真正执行语句的层,执行器有三种方式和存储引擎(一般是innoDB)交互 主键索引查询 查询的条件用到了主键,这个是全表唯一的,优化器会选择const类型来查询,然后while循环去根据主键索引的B树结…...

【目标测距】雷达投影测距
文章目录 前言一、读取点云二、点云投影图片三、读取检测信息四、点云投影测距五、学习交流 前言 雷达点云投影相机。图片目标检测,通过检测框约束等等对目标赋予距离。计算消耗较大,适合离线验证操作。在线操作可以只投影雷达检测框。 一、读取点云 py…...
uniapp、小程序canvas相关
1、圆形or圆形头像 //示例 const ctx uni.createCanvasContext(myCanvas); //canvas const round uni.upx2px(72) / 2; // 半径 const x uni.upx2px(92); //目标x轴位置 const y uni.upx2px(236); //目标y轴位置//if 图片是不是静态资源 async > const imgSrc https:/…...

[工业自动化-23]:西门子S7-15xxx编程 - 软件编程 - 西门子PLC人机界面交互HMI功能概述、硬件环境准备、软件环境准备
目录 一、什么是人机界面 二、什么是PLC人机交互界面HMI 三、人机界面设计的功能列表 四、开发主机与PLC的连接方式 五、开发主机与HMI的连接方式 六、HMI组态 一、什么是人机界面 人机界面是指人与机器或系统之间的交互界面。它是人类与计算机或其他设备之间进行信息交换…...

在Ubuntu系统中安装VNC并结合内网穿透实现公网远程访问
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

java基础练习缺少项目?看这篇文章就够了(上)!
公众号:全干开发 。 专注分享简洁但高质量的动图技术文章! 项目概述 本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常…...
鸿蒙为什么使用typescript 作为开发语言 而不是 flutter 或者 kotlin
猜想如下 dev studio 是基于 idea 二次开发的 ,使用kotlin 应该是更合理 变成 jetbrain 全家桶, 但是 现在android 开发也是kotlin 是不是为了做分割 ,所以不使用kotlin flutter 是谷歌的 安卓也是谷歌的 所以不采用 typescript 是微软的…...

Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用
在我们开发过程中经常会使用到悬浮菜单的使用,当我们滑动到指定位置后,菜单会自动悬浮。 实现效果如下(左为滑动前、右为滑动后): 上述便是通过NestedScrollView 、SliverAppBar实现的效果,通过两个控件我…...
Mongodb 副本集名称重命名
副本集重命名 要重命名副本集,您必须关闭副本集的所有成员,然后使用新的副本集名称配置每个成员的数据库。 此过程需要停机。 先决条件 确保您的副本集未分片。重命名过程仅适用于未分片的副本集。 在重命名副本集之前,请 对 MongoDB 部…...
C#WPF属性触发器实例
本文讲解C#WPF属性触发器的实例 在属性触发器中,当一个属性发生更改时,它将立即或动画更改另一个属性 实例 <Windowx:Class="TriggerDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://sch…...

Kotlin 核心语法,为什么选择Kotlin ?
Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。与Java相比,Kotlin的语法更简洁、更具表达性,而且提供了更多的特性。 Kotlin是使用Java开发者的思维被创建的,Intellij作为它主要的开发IDE。对于 Android开发者&#…...

SpringCloud微服务:Nacos的集群、负载均衡、环境隔离
目录 集群 在user-service的yml文件配置集群 启动服务 负载均衡 order-service配置集群 设置负载均衡 当本地集群的服务挂掉时 访问权重 环境隔离 1、Nacos服务分级存储模型 一级是服务,例如userservice 二级是集群,例如杭州或上海 …...

Selenium+Python做web端自动化测试框架实战
最近受到万点暴击,由于公司业务出现问题,工作任务没那么繁重,有时间摸索seleniumpython自动化测试,结合网上查到的资料自己编写出适合web自动化测试的框架,由于本人也是刚刚开始学习python,这套自动化框架目…...

Linux:安装MySQL服务(非docker方式)
1、下载安装包 下载MySQL安装包,需要Oracle官网的账号 下面是网友提供的账号及密码,亲测有效。 账户:3028064308qq.com 我用的这个,可以登陆 密码:OraclePassword123!Oracle Account: 602205528qq.com Oracle Pass…...
C++实现有理数类 四则运算和输入输出
面试 C 程序员,什么样的问题是好问题? - 知乎 https://www.cnblogs.com/bwjblogs/p/12982908.html...

小鸟飞呀飞
欢迎来到程序小院 小鸟飞呀飞 玩法:鼠标控制小鸟飞翔的方向,点击鼠标左键上升,不要让小鸟掉落,从管道中经过,快去飞呀飞哦^^。开始游戏https://www.ormcc.com/play/gameStart/204 html <canvas width"288&quo…...

Unity 场景烘培 ——unity Post-Processing后处理1(四)
提示:文章有错误的地方,还望诸位大神不吝指教! 文章目录 前言一、Post-Processing是什么?二、安装使用Post-Processing1.安装Post-Processing2.使用Post-Processing(1).添加Post-process Volume(…...

Burpsuite抓HTTPS证书导入问题
Burpsuite证书导出有两种方法: 第一种方法 1、开启代理后直接在浏览器中输入burp下载CA证书 2、在中间证书颁发机构中导入刚导出的证书 3、导入完成后再把这个证书选择导出,另存为cer格式的文件 4、在受信任的根证书颁发机构中导入刚保存的cer格式证书…...
python保存文件到zip压缩包中
这里我们使用zipfile这个库进行操作,保存压缩文件相对简单,只需要指定文件名即可,不需要读取那个文件: with zipfile.ZipFile("zip文件路径", mode, zipfile.ZIP_DEFLATED) as z:z.write("压缩源文件路径", …...

一个简单的德劳内三角剖分实现
德劳内(Delaunay)三角剖分是一种经典的将点集进行三角网格化预处理的手段,在NavMesh、随机地牢生成等场景下都有应用。 具体内容百度一大堆,就不介绍了。 比较知名的算法是Bowyer-Watson算法,也就是逐点插入法。 下雨闲…...

AI浪潮下的IT行业:威胁、转变与共生之道
目录 前言1 AI在IT行业的具体应用场景1.1 软件开发中的AI助手1.2 运维与监控的智能化1.3 测试自动化与质量保障1.4 安全防护中的智能威胁识别 2 AI对IT从业者的实际影响2.1 工作内容的结构性变化2.2 技能结构的再平衡 3 IT从业者不可替代的能力与价值3.1 复杂系统的架构与抽象能…...

FastAPI安全异常处理:从401到422的奇妙冒险
title: FastAPI安全异常处理:从401到422的奇妙冒险 date: 2025/06/05 21:06:31 updated: 2025/06/05 21:06:31 author: cmdragon excerpt: FastAPI安全异常处理核心原理与实践包括认证失败的标准HTTP响应规范、令牌异常的特殊场景处理以及完整示例代码。HTTP状态码选择原则…...
phosphobot开源程序是控制您的 SO-100 和 SO-101 机器人并训练 VLA AI 机器人开源模型
一、软件介绍 文末提供程序和源码下载 phosphobot开源程序是控制您的 SO-100 和 SO-101 机器人并训练 VLA AI 机器人开源模型。 二、Overview 概述 🕹️ Control your robot with the keyboard, a leader arm, a Meta Quest headset or via API 🕹️…...

Rest-Assured API 测试:基于 Java 和 TestNG 的接口自动化测试
1. 右键点击项目的文件夹,选择 New > File。 2. 输入文件名,例如 notes.md,然后点击 OK。 3. 选择项目类型 在左侧的 Generators 部分,选择 Maven Archetype,这将为你生成一个基于 Maven 的项目。 4. 配置项目基…...

机器学习:集成学习概念和分类、随机森林、Adaboost、GBDT
本文目录: 一、集成学习概念**核心思想:** 二、集成学习分类(一)Bagging集成(二)Boosting集成(三)两种集成方法对比 三、随机森林(一)构造过程(二…...
IDEA:配置 Git 需要完成 Git 路径设置、账号认证以及仓库关联三个主要步骤
一、验证 Git 是否已安装 检查 Git 版本(Windows/Linux/Mac): 打开终端 / 命令提示符,输入: git --version若未安装,下载并安装 Git 二、在 IDEA 中配置 Git 路径 打开设置: Windows/Linux&a…...
OD 算法题 B卷【猴子吃桃】
文章目录 猴子吃桃 猴子吃桃 猴子喜欢吃桃,桃园有N棵桃树,第i棵桃树上有Ni个桃,看守将在H(>N)小时后回来;猴子可以决定吃桃的速度K(个/小时),每个小时他会选择一棵桃树,从中吃掉K个桃,如果这…...
使用glide 同步获取图片
在 Glide 中,可以使用asBitmap()方法来获取图片的Bitmap对象,进而同步地加载图片。以下是具体示例: String imageUrl "https://example.com/image.jpg"; Bitmap bitmap Glide.with(context).asBitmap().load(imageUrl).apply(ne…...

ruoyi-plus-could 负载均衡 通过 Gateway模块配置负载均衡
这个很简单的,其实都不用配置。 在nacos中ruoyi-gateway.yml配置文件里面: 其实他已经给我们配置好了,只要uri:lb有【lb】就表示负载均衡配置 我们只需要在启动服务的时候改下端口就可以。 然后通过小工具测试下: 结…...