稀疏数组(sparse array)是一种只为数组中的非零元素分配内存的特殊类型数组,分为三列:
1.行下标
2.列下标
3.值
第一行为总行数、总列数、值的个数,其他行存储了非零元素的下标和值。
根据上图我们可以写出如下代码实现稀疏数组:
package top.baikunlong.sparsearray; import java.io.*; /** * @author baikunlong * @date 2020/10/5 20:38 * @apiNote */ public class SparseArray { public static void main(String[] args) { //创建原数组 int[][] originArray = new int[11][11]; //赋值 originArray[1][2] = 1; originArray[2][3] = 2; int length = originArray.length; System.out.println("原数组:"); //打印一下原数组并得到原数组有效的个数 int count = 0; for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { System.out.print(originArray[i][j] + " "); if (originArray[i][j] != 0) { count++; } } System.out.println(); } System.out.println("有效值个数:" + count); //创建稀疏数组,因为第一行是用来存 行列数 和 值个数(文件读取恢复稀疏数组时会用到这个数) 的,所以要多一行 int[][] sparseArray = new int[count + 1][3]; sparseArray[0][0] = length; sparseArray[0][1] = length; sparseArray[0][2] = count; //给稀疏数组赋值,把原数组里非零的值存起来 int rowIndex=1;//这里需要一个行下标记录下当前存储第几行,第一行已经存了行列数和值个数,所以从第二行开始存 for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { if (originArray[i][j] != 0) { sparseArray[rowIndex][0]=i; sparseArray[rowIndex][1]=j; sparseArray[rowIndex][2]=originArray[i][j]; rowIndex++; } } } System.out.println("稀疏数组:"); for (int i = 0; i < sparseArray.length; i++) { for (int j = 0; j < sparseArray.length; j++) { System.out.print(sparseArray[i][j]+" "); } System.out.println(); } //把稀疏矩阵存入文件SparseArray.data final String fileName = "SparseArray.data"; File file = new File(fileName); try(FileOutputStream out = new FileOutputStream(file)) { int i = 0; for (; i < sparseArray.length-1; i++) { out.write((sparseArray[i][0]+" "+sparseArray[i][1]+" "+sparseArray[i][2]+"\n").getBytes()); } //最后行不用回车 out.write((sparseArray[i][0]+" "+sparseArray[i][1]+" "+sparseArray[i][0]).getBytes()); } catch (IOException e) { e.printStackTrace(); } //========================================================== //到这里我们已经把原数组进行了压缩,使用稀疏数组进行存储,现在要开始读出来,并恢复成原数组 try(BufferedReader reader = new BufferedReader(new FileReader(fileName))) { //读取第一行,用于创建稀疏数组 String s = reader.readLine(); String[] strings = s.split(" "); //注意,这里创建大小用到了第一行第三列那个 值个数 这个值,它加一就是行数了,列数固定还是三 int[][] sparseArrayFromFile = new int[Integer.parseInt(strings[2])+1][3]; //赋值第一行的数据,包含了行列式数和值个数 sparseArrayFromFile[0][0]=Integer.parseInt(strings[0]); sparseArrayFromFile[0][1]=Integer.parseInt(strings[1]); sparseArrayFromFile[0][2]=Integer.parseInt(strings[2]); //开始读取下面的下标和值 rowIndex=1;//行下标 while ((s=reader.readLine())!=null){ strings = s.split(" "); sparseArrayFromFile[rowIndex][0]=Integer.parseInt(strings[0]); sparseArrayFromFile[rowIndex][1]=Integer.parseInt(strings[1]); sparseArrayFromFile[rowIndex][2]=Integer.parseInt(strings[2]); rowIndex++; } //打印文件读取出来的稀疏数组 System.out.println("打印文件读取出来的稀疏数组:"); for (int i = 0; i < sparseArrayFromFile.length; i++) { for (int j = 0; j < sparseArrayFromFile.length; j++) { System.out.print(sparseArrayFromFile[i][j]+" "); } System.out.println(); } //恢复原始数组 int[][] recoveredArray = new int[sparseArrayFromFile[0][0]][sparseArrayFromFile[0][1]]; for (int i = 1; i < sparseArrayFromFile.length; i++) { recoveredArray[sparseArrayFromFile[i][0]][sparseArrayFromFile[i][1]]=sparseArrayFromFile[i][2]; } //打印恢复的数组 System.out.println("打印恢复的数组"); for (int i = 0; i < recoveredArray.length; i++) { for (int j = 0; j < recoveredArray.length; j++) { System.out.print(recoveredArray[i][j]+" "); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); } } }
运行结果如下: