稀疏数组的应用分析

													**引言**

本人是一个Java爱好者,正在学习Java的数据结构与算法,记录一下自己的学习思路,
有需要的小伙伴们可以参考一下,不足的地方欢迎指正:

首先我们来看一个案例:
[以五子棋 存档退出和继续上盘的功能分析为例]

我们要为此棋盘实现存档退出的功能
我们可以考虑使用普通的二维数组来保存棋局0代表无子,1代表黑子,2代表蓝子,那么二维数组为:
在这里插入图片描述

	使用原始的二维数组固然可以保存棋局,但是存在一个问题,数组中大量的元素都是0,无意义的数据,那么我们的稀疏数组派上用场了
	我们可以将此二维数组转化为稀疏数组再保存到本地文件,可以节省空间,当我们需要使用的时候在还原为二维数组
	
	**稀疏数组的特点:
		1.稀疏数组固定三列
		2.第一行的元素存储原数组的总行数列数以及除0以外其他值的个数
		3.其他行用来存储非0值所在的原始数组的行列信息以及值信息**

下面我们来整理一下实现**存盘退出**和**继续上盘**的思路:

	1.[存盘退出]:就是将棋盘数据持久化到本地文件,我们可以这样做:
			**棋盘-->二维数组-->稀疏数组[压缩]--->序列化到本地文件**
	2.[续上盘]: 就是将本地文件中的稀疏数组还原为棋盘,我们可以这样做:
			**读取本地文件-->[得到]稀疏数组-->[还原]二维数组-->还原棋盘**
			[参考文档](https://mermaid-js.github.io/mermaid/#/flowchart?id=graph)

好了,思路就分析到这里了,接下来我们上代码:
public class SparseArrayTest {
	public static void main(String[] args) {
		// 1.创建和初始化原始二维数组
		int[][] oldArray = new int[11][11];
		// 2.根据棋盘为二维数组中的元素赋值
		oldArray[1][2] = 1;
		oldArray[2][3] = 2;
		// 3.将二维数组转化为稀疏数组
		int[][] sparseArray = parseToSparseArray(oldArray);
		// 4.将稀疏数组序列化到文件中
		saveSparseArrayToFile(sparseArray);
		// 5.读取文件 得到稀疏数组
		int[][] arraySparse = readSparseArrayFromLocalFile("array_save.txt");
		// 6.将稀疏数组还原为二维数组
		int[][] oldArray2 = restoreArrayBySparseArray(arraySparse);
		// 7.分别遍历原二维数组、稀疏数组、还原后的二维数组验证结果:
		System.out.println("原数组");
		printArray(oldArray);
		
		System.out.println("稀疏数组");
		printArray(arraySparse);

		System.out.println("还原的二维数组");
		printArray(oldArray2);
	}
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/2020080911083495.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0ODI4MTQ5,size_16,color_FFFFFF,t_70

/*
	将二维数组转化为稀疏数组
*/
private static int[][] parseToSparseArray(int[][] oldArray) {
		int count = 0;//存储原二维数组的特殊值个数
		int row = 0;//记录原二维数组外层数组的长度
		int col = 0;//记录原二维数组内层数组的长度
		for (int i = 0; i < oldArray.length; i++) {
			row++;
			for (int j = 0; j < oldArray[i].length; j++) {
				col++;
				if (oldArray[i][j] != 0) {
					count++;
				}
			}
		}
		// 创建稀疏数组
		int[][] sparseArray = new int[count + 1][3];
		// 稀疏数组第一个位置用来记录原数组的信息
		sparseArray[0] = new int[] { row, col / row, count };
		int k = 1;//记录稀疏数组的下标从1开始
		//遍历原数组 为稀疏数组的元素赋值
		for (int i = 0; i < oldArray.length; i++) {
			for (int j = 0; j < oldArray[i].length; j++) {
				if (oldArray[i][j] != 0) {
					sparseArray[k++] = new int[] { i, j, oldArray[i][j] };
				}
			}
		}
		//得到稀疏数组
		return sparseArray;
	}
/*
	将稀疏数组序列化到文件中
*/
private static void saveSparseArrayToFile(int[][] sparseArray) {
		ObjectOutputStream outputStream = null;
		try {
			//创建流
			outputStream = new ObjectOutputStream(new FileOutputStream(new File("array_save.txt")));
			// 写入文件
			outputStream.writeObject(sparseArray);
			System.out.println("保存成功");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			//关闭流
			try {
				if (outputStream != null)
					outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/*
		从本地文件中读取稀疏数组
	*/
	private static int[][] readSparseArrayFromLocalFile(String path) {
		ObjectInputStream inputStream = null;
		try {
			//创建读入流
			inputStream = new ObjectInputStream(new FileInputStream(new File(path)));
			//读取文件
			return (int[][]) inputStream.readObject();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			//关闭流
			try {
				if (inputStream != null)
					inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/*
		将稀疏数组还原为二维数组
	*/
	private static int[][] restoreArrayBySparseArray(int[][] arraySparse) {
		
		int[][] array = new int[arraySparse[0][0]][arraySparse[0][1]];

		for (int i = 1; i < arraySparse.length; i++) {
			array[arraySparse[i][0]][arraySparse[i][1]] = arraySparse[i][2];
		}
		return array;
	}
	/*
		打印数组
	*/
	private static void printArray(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();
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值