参考于 尚硅谷Java数据结构与java算法,韩顺平数据结构与算法
1.基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
2.应用实例
- 使用稀疏数组, 来保留类似前面的二维数组(棋盘、地图等等)
- 把稀疏 数组存盘,并且可以从新恢复原来的二维数组数
- 整体思路分析:
下图为棋盘数据,用0,1,2分别表示无子,黑子,蓝子。下列文字描述及代码均以此为例!
二维数组转稀疏数组的思路:
- 遍历原始的二维数组,得到有效数据的个数sum
- 根据sum就可以创建稀疏数组sparseArr int[sum+ 1][3] (对应上图)
- 将二维数组的有效数据数据存入到稀疏数组
稀疏数组转原始的二维数组的思路:
1.先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的chessarr2 =int[11][11]。
2.在读取稀疏数組后几行的数据,并赋给原始的二维数组即可。
3.代码实现:
package cn.outakuyu.sparsearray;
import java.io.*;
import java.util.Arrays;
//稀疏数组
public class SparseArray {
public static void main(String[] args) throws IOException {
//创建一个原始的二维数组
//0表示没有棋子,1表示黑子,2表示蓝子
int chessArr1[][]=new int[11][11];
chessArr1[1][2]=1;
chessArr1[2][3]=2;
//输出原始的二维数组
System.out.println("原始的二维数组~~~~~~");
for(int[] row:chessArr1){
for(int data:row){
System.out.print("\t"+data);
}
System.out.println();
}
//将二维数组 转 稀疏数组的思路
//1,先遍历二维数组 得到非0数据的个数
int sum=0;
for(int i=0;i<11;i++){
for(int j=0;j<11;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的值存放到稀疏数组中
int count=0;//用于记录是第几个非0数据
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
if(chessArr1[i][j]!=0){
count++;
//分别对应稀疏数组的 行、列、值
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=chessArr1[i][j];
}
}
}
//输出稀疏数组的形式
System.out.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]);
}
//将稀疏数组 恢复成 原始的二维数组
/*
* 稀疏数组转原始的二维数组的思路
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.out.println();
System.out.println("恢复后的二维数组");
for(int[] row:chessArr2){
for(int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
//扩展:二维数组写入txt与读取
//将稀疏数组写入到txt文件中
String path="D:\\array.txt";
wirteTotxt(sparseArr,path);
//读取稀疏数组
int[][] array1=readToarr(path);
for(int[] row:array1) {
System.out.println(Arrays.toString(row));
}
}
//扩展1:将二维数组写入txt文件中
public static void wirteTotxt(int [][] sparseArr, String path) throws IOException {
OutputStream output = new FileOutputStream(path);
//输出
for (int[] row : sparseArr) {
for (Integer data : row) {
String str=Integer.toString(data);
output.write(str.getBytes("UTF-8"));
output.write("\t".getBytes("UTF-8"));
}
output.write("\n".getBytes("UTF-8"));
}
output.close();
System.out.println("写入完成!");
}
//扩展:读取txt文件中的二维数组,并返回
public static int[][] readToarr(String path) throws IOException {
String s;
try (InputStream input = new FileInputStream(path)) {
int n;
StringBuilder sb = new StringBuilder();
while ((n = input.read()) != -1) {
sb.append((char) n);
}
s = sb.toString();
}
System.out.println(s);
String [] array=s.split("\n");
//System.out.println(String.valueOf(array.length));
int x=array.length;
int y=array[0].split("\t").length;
int [][] array1=new int[x][y];
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
array1[i][j]= Integer.parseInt(array[i].split("\t")[j]);
}
}
return array1;
}
}