数据结构与算法————稀疏数组

引言

数据压缩方面,我们往往可以通过稀疏数组来保存有效数据,节省存储空间。

一、稀疏数组的概念

当一个数组中大部分元素是0,或为同一个值的时候,可以使用稀疏数组来保存数组。

它是一个十分有效的存储结构,便于节省存储空间。

它的处理方式是:

1、记录数组一共有几行几列有多少不同的值

2、把具有不同值的元素的行、列及值记录在一个小规模二维数组中(稀疏数组),从而缩存储数据的规模。

二、稀疏数组的存储结构

稀疏数组实际上是一个典型的二维数组,它描述的是一个标准二维数组的有效数据,如果标准二维数组的内容如下所示的话:

那么这个标准二维数组对应的稀疏数组的结构就如下图所示:

如上图所示。

稀疏数组有固定的三列,分别代表原始二维数组的行、列和值,但是第一行具有特殊的含义:稀疏数组的第一行存储原始数组的行数、列数和有效数据个数,这三个信息。而从第二行(也就是[1]行)开始,才是真正的原始二维数组的有效数据。

【扩展】稀疏数组可以描述二维数组,但同时,我认为它也可以描述更高维的数组,比如三维空间数组,那么相应稀疏数组结构也会有所变化。所以稀疏数组并不是只能描述一个二维数组,凡是可以只保存原始数组有效数据的都可以是稀疏数组,只不过二维数组对应的稀疏数组更有代表性。

三、五子棋盘的保存与复盘

五子棋可能没有几个人没玩过,那么在线上的五子棋游戏中,后台实际上并没有保存整个棋盘,而是利用稀疏数组保存有效数据,下面我们就看看如何通过Java 编写利用稀疏数组对五子棋局的保存与复盘吧。

3.1 五子棋盘的保存

假设在五子棋游戏中,数字1 代表黑子、2 代表白子,0 代表没有任何棋子,棋盘是一个可容纳 11 × 11 个棋子的正方形。黑子先行,双方都下了两步,形成了下面的局势:

public static void main(String[] args) {int[][] chessArr = new int[11][11];chessArr[1][2] = 1;chessArr[2][3] = 2;chessArr[1][4] = 1;chessArr[1][3] = 2;// 输出原始二维数组printArr(chessArr, "原始的二维数组······");
}

其中 printArr()是一个输出二维数组的静态工具方法:

/*** 输出二维数组数组工具方法*/
private static void printArr(int[][] arr, String msg) {System.out.println(msg);for (int[] row : arr) {for (int data : row) {System.out.printf("%d ", data);}System.out.println();}
}

那么这个11 × 11 的二维数组,根据上面介绍的稀疏数组的结构,进行保存,代码如下:

/*** 二维数组转稀疏数组* @param chessArr* @return*/
private static int[][] getSparseArr(int[][] chessArr) {// 将二维数组转为稀疏数组// 1、先遍历二维数组,得到非 0 数据的个数int sum = 0;// 二维数组的 length 取的是行数for (int i = 0; i < chessArr.length; i++) {for (int j = 0; j < chessArr[0].length; j++) {if (chessArr[i][j] != 0) {sum++;}}}
//		System.out.println("sum = " + sum);// 2. 创建对应的稀疏数组int[][] sparseArr = new int[sum + 1][3];// 给稀疏数组赋值sparseArr[0][0] = chessArr.length;sparseArr[0][1] = chessArr[0].length;sparseArr[0][2] = sum;// 将原始数组中的非 0 数据存放到稀疏数组中int sparseArrRow = 1;for (int i = 0; i < chessArr.length; i++) {for (int j = 0; j < chessArr[0].length; j++) {if (chessArr[i][j] != 0) {sparseArr[sparseArrRow][0] = i;sparseArr[sparseArrRow][1] = j;sparseArr[sparseArrRow][2] = chessArr[i][j];sparseArrRow++;}}}return sparseArr;
}

获得稀疏数组后输出:

int[][] sparseArr = getSparseArr(chessArr);
printArr(sparseArr, "输出稀疏数组······");

3.2 稀疏数组复盘五子棋

其实复盘的逻辑要更为简单,首先通过稀疏数组的第一行,初始化一个11 × 11 的二维数组,然后循环后面的行,取出每个数据放入到二维数组中去即可,代码如下:

/*** 复盘,稀疏数组转二维数组* @return*/
private static int[][] getReplayArr(int[][] sparseArr) {int[][] chessArr = new int[sparseArr[0][0]][sparseArr[0][1]];for (int i = 1; i < sparseArr.length; i++) {chessArr[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];}return chessArr;
}

通过上面的内容,我们重新复盘,并输出:

int[][] replayArr = getReplayArr(sparseArr);
printArr(replayArr, "复盘后的二维数组......");

可以看到,复盘后的棋盘与原始棋盘一模一样,这样就达到了利用稀疏数组节省存储空间的效果。

总结

稀疏数组总体来说还是比较简单的一个数据结构的利用,其中并未涉及任何算法,唯一的难点,可能就是二维数组转稀疏数组时的一些数组下标的思考和转化,不过通过画图也可以轻易地找出准确值。

 

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

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

相关文章

Linux进阶之路————crond定时任务调度

引言 crond 的概念和 crontab 是不可分割的。crontab 是一个命令&#xff0c;而 crond 是Linux 下用来周期性执行某种任务或等待处理某些事件的守护进程&#xff0c;类似于 Windows 下的计划任务。 当装完操作系统之后&#xff0c;默认便会安装 crond 服务工具&#xff0c;并…

Maven配置_01

1 下载相应的Maven--->地址:http://maven.apache.org/download.cgi 2 将下载的压缩包解压到自己指定的文件夹 C:\OS\apache-maven-3.5.2 3 配置环境变量 3.1 此电脑-->鼠标右键-->属性-->高级系统设置-->环境变量 3.2 用户变量或者系统变量中选择 新建 输入…

Linux进阶之路————Linux磁盘分区与挂载

引言 对于Linux来说&#xff0c;无论有几个分区&#xff0c;分给哪一目录使用&#xff0c;它归根结底就只有一个根目录 / &#xff0c;一个独立且唯一的文件结构&#xff0c;Linux 中每个分区都是用来组成整个文件系统的一部分。 Linux采用一种叫“载入”的处理方法&#xff…

Spring jndi连接数据库

Spring jndi连接数据库JNDI 即Java命名目录接口 Java Naming Dictory Interface Spring.xml配置文件 <bean name"dbsource1" class"org.springframework.jdbc.core.JdbcTemplate"><property name"jndi" value"java:comp/env/jdbc/…

Maven学习(五)————依赖的特性辨析

引言 在Maven 中&#xff0c;依赖有一些特性必须我们掌握&#xff0c;如依赖的传递性。 一、依赖的传递性 其实依赖的传递性非常好理解。 上图&#xff0c;如果 Maven 项目 B 已经依赖了 C &#xff0c;A 又依赖了 B&#xff0c;那么 A 不需要再在自己的pom 中重复引入 C 的…

ZXing生成二维码

pom.xml <!-- https://mvnrepository.com/artifact/com.google.zxing/core --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.2</version></dependency> ​ ​<!-- ht…

Java NIO————NIO 简介

引言 Java NIO (New IO&#xff0c;或Non Blocking IO) 是从Java1.4 版本开始引入的一个新的 IO API&#xff0c;可以代替标准的Java IO API。 NIO与原来的IO有同样的作用和目的&#xff0c;但是使用的方式完全不同。 NIO支持面向缓冲区、基于通道的IO操作。NIO将以更加高效…

MySql主从同步最小配置

MySql主从同步最小配置 MySql配置文件配置window: my.ini centos: my.cnf主数据库配置 #配置数据库的唯一标识符,一般1位主库,从库为ip地址最后一位 server-id 1 #启用二进制日志,对应mysql-bin.xxxxx文件 log-bin mysql-bin #需要同步的数据库名 binlog-do-dbtest1 #不需要…

解决pom文件第一行报错(unknown)-亲测有效

原文链接&#xff1a;https://blog.csdn.net/u010947534/article/details/93743582 问题&#xff1a; Eclipse导入maven项目时&#xff0c;或者新建一个springboot项目时&#xff0c;pom.xml文件第一行报错&#xff0c;没有错误信息提示&#xff0c;就一个Unknown&#xff0c…

Oracle中start with xx connect by prior 语句解析

Oracle中start with xx connect by prior 语句解析 ​ Oracle这种的start with语句主要对B型树的数据进行递归查询.可以指定数据树上的任一节点,然后查找到它所有的子节点或者父节点. ​ 现在有如下图的数据: 我们先想数据库插入数据,这里用到oracle的批量插入写法# 1 建表 CRE…

Spring Boot————Profile配置

引言 Spring Boot 的Profile配置&#xff0c;可以极大简化配置难度&#xff0c;可以有多种配置形式&#xff0c;根据位置有不同的生效方式。 探讨问题 Spring Boot 的 Profile 配置是为了解决不同环境可能存在的多种配置问题。 举例来说明的话&#xff0c;就是当我们开发完…

Enum的简单使用

package cn.silica.vo;/*** author laibaocen*/ public enum Separator {/*** 枚举值 大写* 如果只有枚举值,那么最后一个枚举值后可以不加分号*/SEMICOLON(0,";","分号"),COLON(1,":","冒号"),CONNECTIVE (2,"-","破折…

Java NIO ———— Buffer 缓冲区详解

引言 缓冲区是一个用于特定基本类型的容器。由java.nio 包定义&#xff0c;所有缓冲区都是 Buffer 抽象类的子类。 Java NIO 中的 Buffer &#xff0c;主要用于与NIO 通道进行交互。数据从通道存入缓冲区&#xff0c;从缓冲区取出到通道中。 一、创建缓冲区 缓冲区的本质是 …

基本类型理解巩固及补码原理总结

引言 本篇文章属于计算机基础通识&#xff0c;主要讨论&#xff1a;有符号类型、无符号类型的区别&#xff0c;byte、int 等类型的取值范围&#xff0c;最大值最小值的计算公式的由来&#xff0c;原码、反码、补码转换公式。 有符号类型与无符号类型 在 Java 中的八大基本类…

2021年3月15日_读书|总结笔记目录

深入理解Java虚拟机*第三版 慢慢填坑第一部分*自动内存管理 第二部分*虚拟机执行子系统 类文件结构 无关性的基石

LeetCode(#118)————杨辉三角形

问题描述 给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例: 输入: 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ] 实现方法 class Solution {public List<List<Intege…

数据结构与算法————九九乘法表

问题描述 通过Java语言实现九九乘法表的输出。使用一个for 循环和两个for循环。 一个for循环 public static void oneFor() {for (int i 1, j 1; i < 9; j) {System.out.print(j "*" i "" i * j "\t");if (j i) {i;j 0;System.ou…

JVM001_类文件结构

无关性的基石 实现语言无关性的基础是虚拟机和字节码存储格式。Java虚拟机不与任何语言绑定&#xff08;包括Java&#xff09;&#xff0c;它只与‘Class文件’这种特定的二进制文件格式所关联。Class文件中包含了Java虚拟机指令集、符号表以及其它辅助信息。出于安全考虑&…

Maven学习(六)————企业Maven项目最佳实践

引言 在《Maven学习&#xff08;三&#xff09;————Maven核心概念&#xff08;二&#xff09;》中&#xff0c;学到了Maven 继承和 Maven 聚合的概念&#xff0c;这两个概念&#xff0c;解决的问题分别是&#xff1a; 1、解决一些公共依赖统一版本的问题。 2、统一打包部署…

Oracle查询表|注释|字段|字段注释

当前用户所有用户DBA备注user_tablesall_tablesdba_tables表user_tab_commentsall_tab_commentsdba_tab_comments表注释user_tab_columnsall_tab_columnsdba_tab_columns表字段user_col_commentsall_col_commentsdba_col_comments字段注释user_objectsall_objectsdba_objects可…