一、基本介绍
1、概念
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用过稀疏数组来保存该数组。
2、稀疏数组存储的原理:
(1) 记录数组一共几行几列,有多少个不同的值
(2)把具有不同值的y元素的行列及值记录在一个小规模的数组中,从而起到缩小规模的作用
例如:
一个大部分元素为0的二维的数组:
[
0
0
0
22
0
0
15
0
11
0
0
0
17
0
0
0
0
−
6
0
0
0
0
0
0
0
0
39
0
91
0
0
0
0
0
0
0
0
28
0
0
0
0
]
\left[ \begin{matrix} 0& 0& 0&22& 0& 0&15\\ 0& 11& 0&0& 0& 17&0\\ 0& 0& 0&-6& 0& 0&0\\ 0& 0& 0&0& 0& 39&0\\ 91& 0& 0&0& 0& 0&0\\ 0& 0& 28&0& 0& 0&0 \end{matrix} \right]
⎣⎢⎢⎢⎢⎢⎢⎡000091001100000000028220−6000000000017039001500000⎦⎥⎥⎥⎥⎥⎥⎤
可以创建一个稀疏数组(sparsearray[n][3])来进行同样的存储,其中:
- sparsearray[0][0]存储原数组中行数
- sparsearray[0][1]存储原数组中列数
- sparsearray[0][2]存储原数组中值的个数
- 其他行表示不为0的值所在原数组中的位置
行 | 列 | 值 | |
---|---|---|---|
[0] | 6 | 7 | 8 |
[1] | 0 | 3 | 22 |
[2] | 0 | 6 | 15 |
[3] | 1 | 1 | 11 |
[4] | 1 | 5 | 17 |
[5] | 2 | 3 | -6 |
[6] | 3 | 5 | 39 |
[7] | 4 | 0 | 91 |
[8] | 5 | 2 | 28 |
所以得到的稀疏数组为:
[
6
7
8
0
3
22
0
6
15
1
1
11
1
5
17
2
3
−
6
3
5
39
4
0
91
5
2
28
]
\left[ \begin{matrix} 6& 7& 8\\ 0& 3& 22\\ 0& 6& 15\\ 1& 1& 11\\ 1& 5& 17\\ 2& 3& -6\\ 3& 5& 39\\ 4& 0& 91\\ 5& 2& 28\\ \end{matrix} \right]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡600112345736153502822151117−6399128⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
从而达到缩小原数组规模的目的
二、例子及代码
1、应用实例
- 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)。
- 使用稀疏数组存盘,并且可以重新恢复为原来的二维数组。
2、代码实现(java)
import java.io.*;
/**
* @author dankejun
* @create 2020-03-20 10:28
*/
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][2] = 1;
chessArr1[2][3] = 2;
chessArr1[4][5] = 2;
//输出原始的二维数组
System.out.println("原始的二维数组:");
for (int[] row : chessArr1) {
for (int data : row) {
System.out.printf("%d\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++;
}
}
}
//2.创建对应的稀疏数组
int[][] sparseArr = new int[sum+1][3];
//给稀疏数组赋值
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
//遍历二维数组,将非0的值存到稀疏数组
int count = 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]);
}
System.out.println();
//将稀疏数组返回为二维数组
//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("还原的稀疏数组为:");
for (int[] row : chessArr2) {
for (int i : row) {
System.out.printf("%d\t", i);
}
System.out.println();
}
//将用稀疏数导出到本地文件保存
//从文件读取系数数组恢复到原来的数组
FileWriter os = null;
FileReader fr = null;
BufferedReader bfr = null;
File file = null;
int[][] sparseArr1 = new int[0][];
try {
file = new File("map.txt");
os = new FileWriter(file);
for (int i = 0; i < sum+1; i++) {
String s = "";
for (int j = 0; j < 3; j++) {
s += sparseArr[i][j] + " ";
}
os.write(s+"\n");
}
System.out.println("\n" + "稀疏数组已经保存到文件:" + file.getName() + "\n");
fr = new FileReader(new File("map.txt"));
bfr = new BufferedReader(fr);
String line = "";
String[] str = null;
sparseArr1 = new int[sum+1][3];
while ((line = bfr.readLine()) != null) {
str = line.split(" ");
for (int i = 0; i < sum + 1; i++) {
for (int j = 0; j < 3; j++) {
sparseArr1[i][j] = Integer.parseInt(str[j]);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bfr != null)
bfr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("恢复的稀疏数组为:");
for (int i = 0; i < sparseArr1.length; i++) {
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
}
}
}
这里将稀疏数组保存到文件以及读取文件中的稀疏数组并还原到原数组直接写到一起了,没有定义单独的方法,所以程序运行结果如下:
- 稀疏数组的创建及还原:
- 稀疏数组写入文件以及从文件中读取稀疏数组并显示: