一、引出稀疏数组
1、先看一个实际的需求
编写的五子棋程序中,有存盘退出和续上盘的功能。
2、分析问题:
因为该二维数组的很多值是默认值0, 因此记录了很多没有意义的数据.->稀疏数组。
二、稀疏数组的基本介绍
1、应用场景
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
2、稀疏数组的处理方法
1)记录数组一共有几行几列,有多少个不同的值
2)把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
3、稀疏数组举例说明
三、应用实例
1、问题
1)使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
2)将稀疏数组保存到磁盘上,比如 map.data
3)恢复原来的稀疏数组时,读取map.data 进行恢复
4)恢复原来的二维数组时,读取稀疏数组进行恢复
2、整体思路分析
四、代码实现
1、打印二维数组
public static void print2DArray(int[][] array) {
for (int[] row : array) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
}
2、将二维数组转换为稀疏数组
public static List<int[]> toSparseArray(int[][] array) { List<int[]> sparseArray = new ArrayList<>(); // 添加稀疏数组的第一行的值(行数 列数 ?) sparseArray.add(new int[]{array.length, array[0].length, 0}); int nonZeroCount = 0;// 用于记录是第几个非0数据 for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { // 添加非零数据 if (array[i][j] != 0) { sparseArray.add(new int[]{i, j, array[i][j]}); nonZeroCount++; } } } //添加第一行的第三个数据:非零数据的数量 sparseArray.get(0)[2] = nonZeroCount; return sparseArray; }
3、打印稀疏数组
public static void printSparseArray(List<int[]> sparseArray) { for (int[] triplet : sparseArray) { System.out.println(triplet[0] + " " + triplet[1] + " " + triplet[2]); } }
4、将稀疏数组保存到文件
public static void saveSparseArray(List<int[]> sparseArray, String filename) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { for (int[] triplet : sparseArray) { writer.write(triplet[0] + " " + triplet[1] + " " + triplet[2]); writer.newLine(); } } catch (IOException e) { e.printStackTrace(); } }
5、打印文件内容
public static void printFileContent(String filename) { System.out.println("文件的内容:"); try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { String line;// 用于获取文件一行的值 // 文件此行不为空,则打印此行 while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } }
6、从文件加载稀疏数组
public static List<int[]> loadSparseArray(String filename) { List<int[]> sparseArray = new ArrayList<>(); try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { String line;// 用于获取文件一行的值 // 文件此行不为空,则获取此行内容 while ((line = reader.readLine()) != null) { String[] parts = line.split(" ");// 每行按空格分割 sparseArray.add(new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])}); } } catch (IOException e) { e.printStackTrace(); } return sparseArray; }
7、将稀疏数组转换回原始二维数组
public static int[][] toOriginalArray(List<int[]> sparseArray, int rows, int cols) { int[][] array = new int[rows][cols]; for (int i = 1; i < sparseArray.size(); i++) { int[] triplet = sparseArray.get(i); array[triplet[0]][triplet[1]] = triplet[2]; } return array; }
8、主函数测试
public class SparseArray { public static void main(String[] args) { // 创建一个原始的二维数组 int[][] originalArray = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; System.out.println("二维数组内容:"); print2DArray(originalArray); // 将二维数组转换为稀疏数组 List<int[]> sparseArray = toSparseArray(originalArray); System.out.println("(将二维数组转换为稀疏数组)稀疏数组内容:"); printSparseArray(sparseArray); String filename = "src\\SparseArray\\map.data"; // 保存稀疏数组到文件 saveSparseArray(sparseArray, filename); System.out.print("(保存稀疏数组到文件)"); printFileContent(filename); // 从文件读取稀疏数组 List<int[]> loadedSparseArray = loadSparseArray(filename); System.out.println("(从文件读取稀疏数组)稀疏数组内容:"); printSparseArray(loadedSparseArray); // 将稀疏数组转换回原始二维数组 // loadedSparseArray.get(0)[0]// 获取行数 // loadedSparseArray.get(0)[1]// 获取列数 int[][] restoredArray = toOriginalArray(loadedSparseArray, loadedSparseArray.get(0)[0], loadedSparseArray.get(0)[1]); System.out.println("(将稀疏数组转换回原始二维数组)二维数组内容:"); print2DArray(restoredArray); }
附件
完整代码
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class SparseArray {
public static void main(String[] args) {
// 创建一个原始的二维数组
int[][] originalArray = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
System.out.println("二维数组内容:");
print2DArray(originalArray);
// 将二维数组转换为稀疏数组
List<int[]> sparseArray = toSparseArray(originalArray);
System.out.println("(将二维数组转换为稀疏数组)稀疏数组内容:");
printSparseArray(sparseArray);
String filename = "src\\SparseArray\\map.data";
// 保存稀疏数组到文件
saveSparseArray(sparseArray, filename);
System.out.print("(保存稀疏数组到文件)");
printFileContent(filename);
// 从文件读取稀疏数组
List<int[]> loadedSparseArray = loadSparseArray(filename);
System.out.println("(从文件读取稀疏数组)稀疏数组内容:");
printSparseArray(loadedSparseArray);
// 将稀疏数组转换回原始二维数组
// loadedSparseArray.get(0)[0]// 获取行数
// loadedSparseArray.get(0)[1]// 获取列数
int[][] restoredArray = toOriginalArray(loadedSparseArray, loadedSparseArray.get(0)[0], loadedSparseArray.get(0)[1]);
System.out.println("(将稀疏数组转换回原始二维数组)二维数组内容:");
print2DArray(restoredArray);
}
// 打印二维数组
public static void print2DArray(int[][] array) {
for (int[] row : array) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
}
// 将二维数组转换为稀疏数组
public static List<int[]> toSparseArray(int[][] array) {
List<int[]> sparseArray = new ArrayList<>();
// 添加稀疏数组的第一行的值(行数 列数 ?)
sparseArray.add(new int[]{array.length, array[0].length, 0});
int nonZeroCount = 0;// 用于记录是第几个非0数据
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
// 添加非零数据
if (array[i][j] != 0) {
sparseArray.add(new int[]{i, j, array[i][j]});
nonZeroCount++;
}
}
}
//添加第一行的第三个数据:非零数据的数量
sparseArray.get(0)[2] = nonZeroCount;
return sparseArray;
}
// 打印稀疏数组
public static void printSparseArray(List<int[]> sparseArray) {
for (int[] triplet : sparseArray) {
System.out.println(triplet[0] + " " + triplet[1] + " " + triplet[2]);
}
}
// 将稀疏数组保存到文件
public static void saveSparseArray(List<int[]> sparseArray, String filename) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
for (int[] triplet : sparseArray) {
writer.write(triplet[0] + " " + triplet[1] + " " + triplet[2]);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 打印文件内容
public static void printFileContent(String filename) {
System.out.println("文件的内容:");
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;// 用于获取文件一行的值
// 文件此行不为空,则打印此行
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 从文件加载稀疏数组
public static List<int[]> loadSparseArray(String filename) {
List<int[]> sparseArray = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;// 用于获取文件一行的值
// 文件此行不为空,则获取此行内容
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ");// 每行按空格分割
sparseArray.add(new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])});
}
} catch (IOException e) {
e.printStackTrace();
}
return sparseArray;
}
// 将稀疏数组转换回原始二维数组
public static int[][] toOriginalArray(List<int[]> sparseArray, int rows, int cols) {
int[][] array = new int[rows][cols];
for (int i = 1; i < sparseArray.size(); i++) {
int[] triplet = sparseArray.get(i);
array[triplet[0]][triplet[1]] = triplet[2];
}
return array;
}
}