什么是稀疏数组?稀疏数组详解

什么是稀疏数组?稀疏数组详解1 背景如下图所示 这里有一个 15 15 的棋盘 如果现在要让你通过编码的方式 让你将这盘棋局保存起来 你会怎么做呢 面对行列数据的保存 我相信大多人第一时间都会想到用二维数组进行保存 2 普通数组保存棋盘数据比如 我们可以将棋盘进行抽象化 用一个 15 15 的二维数组来表示 然后用 0 表示空点 用 1 表示白子 用 2 表示黑子 于是就可以抽象为如下模样 于是 我们可以通过如下代码 将数据保存到二维数组中 将棋盘数据保存为二维数组

【1】背景

如下图所示,这里有一个 15 × 15 的棋盘,如果现在要让你通过编码的方式,让你将这盘棋局保存起来,你会怎么做呢?

面对行列数据的保存,我相信大多人第一时间都会想到用二维数组进行保存。

什么是稀疏数组?稀疏数组详解

【2】普通数组保存棋盘数据

比如,我们可以将棋盘进行抽象化,用一个 15 × 15 的二维数组来表示,然后用 0 表示空点,用 1 表示白子,用 2 表示黑子,于是就可以抽象为如下模样。

什么是稀疏数组?稀疏数组详解

于是,我们可以通过如下代码,将数据保存到二维数组中。

/ * 将棋盘数据保存为二维数组 */ public static int[][] saveChess() { // 初始化棋盘(大小为 15 * 15),int默认为0(即空点) int[][] arr = new int[15][15]; // 保存白子(用1表示) arr[5][5] = 1; arr[7][5] = 1; arr[6][7] = 1; // 保存黑子(用2表示) arr[6][6] = 2; arr[7][6] = 2; arr[8][6] = 2; arr[7][7] = 2; return arr; } 

【3】普通数组的不足之处

上面,我们通过了一个最普通的方法,将棋盘数据保存在了一个二维数组中,整个数组我们用了 15 × 15(共 225)个点来保存数据,其中有 218 个点都是空的。实际来说,我们只需要将有价值的黑白子保存起来即可,因为只要我们知道黑白子数据,以及棋盘的大小,那么这 218 个空点是可以不用进行保存的。

把这样没有价值的数据起来,不但会浪费存储空间的大小,如果写入到磁盘中,还会增大 IO 的读写量,影响性能,这就是用普通二维数组来表示棋盘数据的不足之处。

那么,针对以上情况,我们该如何将我们的数据格式进行优化呢?于是就引出了我们接下来的稀疏数组的概念。

【4】稀疏数组

所谓稀疏数组,从字面上我们也可以得知,它仍然是一个数组,他的作用就是将一个对应的数组数据进行优化,比如,我们将上面的二维数组进行优化。

什么是稀疏数组?稀疏数组详解

我们可以定义一个数组,只记录黑白子的数据,具体如下:

什么是稀疏数组?稀疏数组详解

从这个表中,我们可以只看到有价值的数据了,如果我们再将这个表抽象为一个二维数组,那么他的大小就是 7 * 3 = 21 个点了。

这相对之前的200多个点来说,确实少了许多节点,节省了很多存储空间。

但只这样保存也是不够的,因为我们并没有保存原棋盘的大小,那么我们不妨约定增加一行,保存原来棋盘的大小(二维数组的大小),那么我们可以用如下进行表示:

什么是稀疏数组?稀疏数组详解

这里我们约定用第1行数据来记录原二维数组的规模,第 1 个值为原数组总行数,第 2 个值为原数组列数,第 3 个值为有价值数据的总数。

这样,我们就将原数组数据,优化为了一个稀疏数组。

【4】二维数组转稀疏数组

根据上面的原理,我们就可以通过代码方式,将原来的普通二维数组,优化为一个稀疏数组了,具体编码如下:

/ * 普通数组转稀疏数组 * * @param arr_普通数组 * @return 稀疏数组 */ public static int[][] castSparseArray(int[][] arr) { // 原数组的总行数 int row = arr.length; // 原数组的总列数 int cloumn = arr[0].length; // 获取黑白子总数 int sum = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { if (arr[i][j] != 0) { sum++; } } } // 创建稀疏数组(sum+1 行表示 sum 个黑白子 + 1行规模) int[][] sparseArray = new int[sum + 1][3]; // 第 1 行原二维数组的行、列、棋子总数 sparseArray[0][0] = row; sparseArray[0][1] = cloumn; sparseArray[0][2] = sum; // 第 2 行开始存具体数据(每行都是一个棋子数据) int sparseRow = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { if (arr[i][j] != 0) { sparseRow++; sparseArray[sparseRow][0] = i; sparseArray[sparseRow][1] = j; sparseArray[sparseRow][2] = arr[i][j]; } } } return sparseArray; }

【5】稀疏数组转二维数组

我们用稀疏数组保存数据,主要是为了节省磁盘空间,优化 IO 读写性能,但在最终复原棋盘的时候,我们还是需要将稀疏数组的数据转化为原普通二维数组数据,那么我们又将如何通过编码的方式去实现稀疏数组转二维数组呢?对应编码如下:

/ * 稀疏数组转普通数组 * * @param sparseArr_稀疏数组 * @return 普通二维数组 */ public static int[][] castToArray(int[][] sparseArr) { // 获取稀疏数组第 1 行(记录了原数组的总行数和总列数) int[] rowFirst = sparseArr[0]; // 初始化数组(棋盘) int row = rowFirst[0]; int column = rowFirst[1]; int[][] arr = new int[row][column]; // 初始化数据(黑白子) for (int i = 1; i < sparseArr.length; i++) { int[] sparseRow = sparseArr[i]; arr[sparseRow[0]][sparseRow[1]] = sparseRow[2]; } return arr; }

这样,我们就可以将稀疏数组还原为普通数组了。

【总结】

在存储数组数据的时候,我们如果存在许多默认值的数据,不妨用稀疏数组来进行存储,这样数据相对来说就会瘦小很多,不但可以节省磁盘空间,还可以优化磁盘读写时性能。

最后附上相关的整段代码:

/ * 二维数组与稀疏数组 * * @author ZhangYuanqiang * @since 2021年5月13日 */ public class SparseArrayTest { public static void main(String[] args) { // 用二维数组保存棋盘 int[][] arr = saveChess(); // 打印二维数组 print(arr); // 将二维数组转化为稀疏数组 int[][] sparseArr = castSparseArray(arr); // 打印稀疏数组 print(sparseArr); // 稀疏数组转二位数组 int[][] arr2 = castToArray(sparseArr); print(arr2); } / * 打印普通数组 */ public static void print(int[][] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j] + "\t"); } System.out.println(); } System.out.println("--------------------------------------"); } / * 将棋盘数据保存为二维数组 */ public static int[][] saveChess() { // 初始化棋盘(大小为 15 * 15) int[][] arr = new int[15][15]; // 保存白子(用1表示) arr[5][5] = 1; arr[7][5] = 1; arr[6][7] = 1; // 保存黑子(用2表示) arr[6][6] = 2; arr[7][6] = 2; arr[8][6] = 2; arr[7][7] = 2; return arr; } / * 普通数组转稀疏数组 * * @param arr_普通数组 * @return 稀疏数组 */ public static int[][] castSparseArray(int[][] arr) { // 原数组的总行数 int row = arr.length; // 原数组的总列数 int cloumn = arr[0].length; // 获取黑白子总数 int sum = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { if (arr[i][j] != 0) { sum++; } } } // 创建稀疏数组(sum+1 行表示 sum 个黑白子 + 1行规模) int[][] sparseArray = new int[sum + 1][3]; // 第 1 行原二维数组的行、列、棋子总数 sparseArray[0][0] = row; sparseArray[0][1] = cloumn; sparseArray[0][2] = sum; // 第 2 行开始存具体数据(每行都是一个棋子数据) int sparseRow = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { if (arr[i][j] != 0) { sparseRow++; sparseArray[sparseRow][0] = i; sparseArray[sparseRow][1] = j; sparseArray[sparseRow][2] = arr[i][j]; } } } return sparseArray; } / * 稀疏数组转普通数组 * * @param sparseArr_稀疏数组 * @return 普通二维数组 */ public static int[][] castToArray(int[][] sparseArr) { // 获取稀疏数组第 1 行(记录了原数组的总行数和总列数) int[] rowFirst = sparseArr[0]; // 初始化数组(棋盘) int row = rowFirst[0]; int column = rowFirst[1]; int[][] arr = new int[row][column]; // 初始化数据(黑白子) for (int i = 1; i < sparseArr.length; i++) { int[] sparseRow = sparseArr[i]; arr[sparseRow[0]][sparseRow[1]] = sparseRow[2]; } return arr; } } 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/198576.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午2:53
下一篇 2026年3月26日 下午2:54


相关推荐

  • cocoapods安装过程_如何开发ios应用

    cocoapods安装过程_如何开发ios应用原文链接: iOS开发-CocoaPods安装和使用教程本文是对原文一些错误的修正已经添加了自己的理解。CocoaPods安装和使用教程Code4App原创文章。转载请注明出处:http://code4app.com/article/cocoapods-install-usage目录CocoaPods是什么?如何下载和安装CocoaPods?如何使用CocoaPods?场景1:利用CocoaP

    2025年8月22日
    3
  • Charles抓包安卓端

    Charles抓包安卓端Charles抓包安卓端电脑和手机须要在同一个WIFI下安装好CharlesAndroid手机一部->接下来会以(一加手机)测试1.打开Charles依次选择Proxy->ProxySettings…在这里插入图片描述2.安装需要的证书依次选择Help->SSLProxying->installCharlesRootCertif…

    2022年5月15日
    64
  • apache日志格式定义及示例说明[通俗易懂]

    apache日志格式定义及示例说明[通俗易懂]来源:https://blog.csdn.net/newhappy2008/article/details/7604956有时候我们需要定制Apache默认日志的格式和内容,比如增加或减少日志所记录的信息、改变默认日志文件的格式等。本文介绍可以用日志记录的所有信息,以及如何设置Apache使其记录这些信息。一、Apache日志格式定义  很久以前,日志文件只有一种格式,这就是“公共…

    2022年5月11日
    41
  • 能源预测:回顾与展望(IEEE论文)

    能源预测:回顾与展望(IEEE论文)EnergyForecasting:AReviewandOutlook—阅读笔记。

    2022年5月3日
    68
  • linux命令chmod 777_chmod无法访问 没有那个文件或目录

    linux命令chmod 777_chmod无法访问 没有那个文件或目录Linux的常用命令一、基本理论知识二、关于文件权限的命令一、基本理论知识二、关于文件权限的命令chgrp(changegroup的简写)命令可以更改文件的所属组,格式为chgrp[组名][文件名]

    2022年8月30日
    4
  • 企业web建站平台—格子平台采用云计算

    企业web建站平台—格子平台采用云计算运用最先进的IT技术——“云计算”,将互联网上各种实用的、有趣的、新奇的元素都浓缩到一个格子里,并且将所有格子都联接在一起,为用户提供出色的价值体验,这就是格子“云”平台。√您只需要注册一个账

    2022年7月3日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号