当一个数组中大部分元素为0而非0元素很少,或者为同一个值的数组时,可以使用稀疏数组来保存该数组,从而降低内存的消耗。
如果原二维数组是n*n的数组,其中非0元素的数据共有m个,则稀疏数组为(m+1) * 3的数组,第一行存储二维数组的行、列以及非0元素的总数,其余各行分别存放非0元素所在行、所在列以及元素值。
下面是代码实现:
将二维数组转化成为稀疏数组,并利用IO流写入到文件中,从文件中进行读取并将其恢复成为原二维数组。
package com.atguigu.sparsearray;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class SparseArray {
public static void main(String[] args){
//创建一个二维数组
int chessArr1[][] = new int[11][11];
//非0数据
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[4][3] = 2;
//输出原始的二维数组
System.out.println("原始的二维数组为:");
for(int[] row : chessArr1) {
for(int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
//遍历二维数组
int sum =0; //保存非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);
//创建稀疏数组
int sparseArr[][] = new int[sum+1][3];
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
//遍历二维数组
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[] row : sparseArr) {
for(int data : row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
//将稀疏数组写入文件
writeTotext(sparseArr, "D:\\JavaProject\\others\\data.txt");
//从文件中读取稀疏数组
int[][] sparseArr2 = null;
try {
sparseArr2 = readFromTxt("D:\\JavaProject\\others\\data.txt");
} catch (IOException e) {
e.printStackTrace();
}
//将稀疏数组恢复成二维数组
//创建出二维数组
int chessArr2[][] = new int[chessArr2[0][0]][chessArr2[0][1]];
//将稀疏数组的后几行数据放入二维数组当中
for (int i = 1; i < chessArr2.length; i++) {
chessArr2[chessArr2[i][0]][chessArr2[i][1]] = chessArr2[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();
}
}
//将数据写入文件中
public static void writeTotext(int[][] array, String path) {
File file = new File(path);
//创建字符输出流
FileWriter writer = null;
try {
writer = new FileWriter(file, true);
//写数据
for (int i = 0; i < array.length; i++) {
writer.write(array[i][0] + " ");
writer.write(array[i][1] + " ");
writer.write(array[i][2] + " " + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
//关闭流
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//将文件中的稀疏数组读出文件
public static int[][] readFromTxt(String path) throws IOException {
File file = new File(path);
int[][] sparseArr = null; //创建稀疏数组
BufferedReader bufferedReader = null; //缓冲流
try {
bufferedReader = new BufferedReader(new FileReader(file));
//获取稀疏数组的大小
int sum = 0;
while (bufferedReader.readLine() != null) {
sum++;
}
sparseArr = new int[sum][3];
//读完之后关闭流,防止后面读到的为空
bufferedReader.close();
//重新打开流
bufferedReader = new BufferedReader(new FileReader(file));
String strs = bufferedReader.readLine(); //读的每一行都是字符串
int i = 0; //指向稀疏数组行的指针
int j = 0; //指向稀疏数组列的指针
while(strs != null) {
String[] str = strs.split(" "); //将读到的字符串以" "分开,得到一个数组
for (String s : str) {
sparseArr[i][j] = Integer.parseInt(s); //将字符串转换成int存储在字符串上
j++; //指向列的指针每遍历一下自增一次
}
j = 0; //一次遍历后,指向列的指针要重新设为0
i++; //行指针自增
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (bufferedReader != null) {
bufferedReader.close();
}
return sparseArr;
}
}
运行代码后,控制台输出如下:
而代码中的文件路径中,也存放了经二维数组转化后的稀疏数组。