稀疏数组就是一个数组中大部分元素都未被使用或者为0,这种数组会造成内存的浪费,所以可以通过一种压缩的方式来表示稀疏数组的内容。
压缩方式:
1.记录数组一共有几行几列,有多少个非零的值
2.把非零元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模,其转化如下图:
压缩后的稀疏数组是一个n行3列的数组,其中第一行分别记录原始数组中的行数、列数和非零元素个数;从第二行开始,每行分别记录原始数组中第1-n个非零元素的行索引、列索引和元素值。
实现代码如下:
public class SparseArray {
public static void main(String[] args) throws Exception {
//创建原始数组11*11
int[][] srcArray = new int[11][11];
srcArray[1][2] = 1;
srcArray[2][3] = 2;
//打印原始数组
printArr(srcArray);
System.out.println("-----------原始数组↑--------------");
//将二维数组转成稀疏数组
//获取原始数组的行数和列数
int srcRows = srcArray.length;
int srcColumns = srcArray[0].length;
//1.先遍历数组,获得数组中非0数据的个数
int sum = 0;
for (int[] row : srcArray) {
for (int data : row) {
if (data != 0) {
sum++;
}
}
}
//2.得到数组中非0数据的个数后,初始化稀疏数组
int[][] sparseArray = new int[sum + 1][3];
//3.给稀疏数组第一行赋值
sparseArray[0][0] = srcRows;
sparseArray[0][1] = srcColumns;
sparseArray[0][2] = sum;
//4.遍历原始数组,将非零数值以及其行和列赋给稀疏数组的相应位置
int index = 1;//从稀疏数组的第二行开始
for (int i = 0; i < srcRows; i++) {
for (int j = 0; j < srcColumns; j++) {
if (srcArray[i][j] != 0) {
sparseArray[index][0] = i;
sparseArray[index][1] = j;
sparseArray[index][2] = srcArray[i][j];
index++;
}
}
}
//打印稀疏数组
printArr(sparseArray);
System.out.println("-----------稀疏数组↑--------------");
//将稀疏数组恢复成原始数组
//1.获取稀疏数组的第一行的前两个元素,得到原始数组的行和列
int[][] srcArray2 = new int[sparseArray[0][0]][sparseArray[0][1]];
//2.从稀疏数组的第二行开始,获取非零数值及其行和列,赋给原始数组中相应的元素
for (int i = 1; i < sparseArray.length; i++) {
srcArray2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
//打印原始数组
printArr(srcArray2);
System.out.println("-----------原始数组↑--------------");
//将稀疏数组持久化到本地磁盘
File file = new File("e:\\array.txt");
FileWriter fileWriter = new FileWriter(file);
for (int[] row : sparseArray) {
for (int data : row) {
fileWriter.write(data + "\t");
}
fileWriter.write("\r\n");
}
fileWriter.close();
//将稀疏数组从文件中读取出来
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
List<int[]> list = new ArrayList<>();//该集合用于保存文件中的每一行数组
while ((line = reader.readLine()) != null) {
//通过Stream流处理将文件中每一行数据转化成整型数组
list.add(Stream.of(line.split("\t")).map(Integer::parseInt).mapToInt(Integer::intValue).toArray());
}
int row = list.size();
int column = list.get(0).length;
int[][] sparseArray2 = new int[row][column];
for (int i = 0; i < row; i++) {
sparseArray2[i] = list.get(i);
}
//打印稀疏数组
printArr(sparseArray2);
System.out.println("-----------稀疏数组↑--------------");
}
private static void printArr(int[][] arr) {
//打印原始数组
for (int[] row : arr) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
}