(所有源码均在 https://github.com/zongzhec/AlgoPractise)
Table of Contents
基本介绍
转换方法
源码
主类
输出
稀疏数组类
其他工具类
ArrayUtil 类
FileUtil 类
当一个数组中大部分元素时0,或者为同一个值的数组时,可以使用稀疏数组来保存改数据
1. 记录数组一共有几行几列,有多少个不同的值;
2. 把具有不同值的元素的行列即值记录在一个小规模的数组中,从而缩小程序的规模
package foo.zongzhe.line.array;
import foo.zongzhe.utils.ArrayUtil;
import foo.zongzhe.utils.FileUtil;
import java.util.ArrayList;
import static foo.zongzhe.utils.Constants.PIPE;
/**
* 稀疏数组
*/
public class SparseArrayDemo {
public static void main(String[] args) {
// 初始化一个二维数组
int[][] twoDimenArray = initializeTwoDimenArray();
ArrayUtil.printArraySize(twoDimenArray, "twoDimenArray");
// 转换成稀疏数组
int[][] sparseArray = SparseArray.twoDimenArrayToSparseArray(twoDimenArray);
ArrayUtil.printArraySize(sparseArray, "sparseArray");
// 还原成二维数组
int[][] revertedTwoDimenArray =SparseArray.sparseArrayToTwoDimenArray(sparseArray);
}
private static int[][] initializeTwoDimenArray() {
// 首先尝试读取文件
ArrayList arrayFileContent = FileUtil.readFile("src/main/resources/foo/zongzhe/line/array/TwoDimenArrayInput.txt");
if (arrayFileContent == null || arrayFileContent.isEmpty()) {
// 文件无法读取或者为空,则手动生成
arrayFileContent.add("0|0|0|22|0|0|15");
arrayFileContent.add("0|11|0|0|0|17|0");
arrayFileContent.add("0|0|0|-6|0|0|0");
arrayFileContent.add("0|0|0|0|0|39|0");
arrayFileContent.add("91|0|0|0|0|0|0");
arrayFileContent.add("0|0|28|0|0|0|0");
}
// 初始化数组信息
int rows = arrayFileContent.size();
int cols = arrayFileContent.get(0).split(PIPE).length;
System.out.println(String.format("Array from input contains %d rows and %d columns", rows, cols));
int[][] twoDimenArray = new int[rows][cols];
// 解析成数组
int currentRow = 0;
int currentCol = 0;
for (String line : arrayFileContent) {
String[] strs = line.split(PIPE);
for (String str : strs) {
twoDimenArray[currentRow][currentCol] = Integer.parseInt(str);
currentCol++;
}
currentCol = 0;
currentRow++;
}
// 输出数组信息
ArrayUtil.printArray(twoDimenArray);
return twoDimenArray;
}
}
Array from input contains 6 rows and 7 columns
Size of twoDimenArray is (6 * 7 =) 42
Size of sparseArray is (9 * 3 =) 27
可以看到,稀疏数组减少了1/3的数据量。
package foo.zongzhe.line.array;
import foo.zongzhe.utils.ArrayUtil;
public class SparseArray {
/**
* 将二维数组转化为稀疏数组
* 1. 记录数组一共有几行几列,有多少个不同的值;
* 2. 把具有不同值的元素的行列即值记录在一个小规模的数组中,从而缩小程序的规模
* Sample Input:
* 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
*
* Expected Output:
* 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
*/
public static int[][] twoDimenArrayToSparseArray(int[][] twoDimenArray) {
int rows = twoDimenArray.length;
int cols = twoDimenArray[0].length;
// 遍历数组,记录值的个数,从而初始化稀疏数组
int valueCount = 0;
for (int[] ints : twoDimenArray) {
for (int anInt : ints) {
if (anInt != 0) {
valueCount++;
}
}
}
int[][] sparseArray = new int[valueCount + 1][3];
// 再次遍历数组,记录每一个值
sparseArray[0][0] = rows;
sparseArray[0][1] = cols;
sparseArray[0][2] = valueCount;
int curRow = 1;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (twoDimenArray[i][j] != 0) {
sparseArray[curRow][0] = i;
sparseArray[curRow][1] = j;
sparseArray[curRow][2] = twoDimenArray[i][j];
curRow++;
}
}
}
// ArrayUtil.printArray(sparseArray);
return sparseArray;
}
/**
* 将稀疏数组转化为二维数组
*
* Sample Input:
* 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
*
* Expected Output:
* 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
*/
public static int[][] sparseArrayToTwoDimenArray(int[][] sparseArray) {
int rows = sparseArray[0][0];
int cols = sparseArray[0][1];
int[][] twoDimenArray = new int[rows][cols];
// initialize two-dimensional array with default value
twoDimenArray = ArrayUtil.initArray(twoDimenArray, 0);
for (int i = 1; i < sparseArray.length; i++) {
twoDimenArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
// ArrayUtil.printArray(twoDimenArray);
return twoDimenArray;
}
}
详见:https://github.com/zongzhec/AlgoPractise
package foo.zongzhe.utils;
public class ArrayUtil {
public static void printArray(int[][] inputArray) {
for (int i = 0; i < inputArray.length; i++) {
for (int j = 0; j < inputArray[i].length; j++) {
System.out.print(inputArray[i][j] + "\t");
}
System.out.println();
}
}
/**
* Initialize Array with default values
*
* @param array Array to be initialized
* @param defaultValue default value
*/
public static int[][] initArray(int[][] array, int defaultValue) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
array[i][j] = defaultValue;
}
}
return array;
}
/**
* Calculates "size" of an array, generally it is row * col
*
* @param array Array to be calculate
* @param arrayDesc Array Description
*/
public static void printArraySize(int[][] array, String arrayDesc) {
int row = array.length;
int col = array[0].length;
System.out.println(String.format("Size of %s is (%d * %d =) %d ", arrayDesc, row, col, (row * col)));
}
}
package foo.zongzhe.utils;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class FileUtil {
public static void main(String[] args) {
}
public static ArrayList readFile(String path) {
ArrayList fileContent = new ArrayList<>();
File file = new File(path);
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("ERROR: File not found in " + path);
e.printStackTrace();
}
InputStreamReader reader = new InputStreamReader(is);
Scanner s = new Scanner(reader); //.useDelimiter("\t");
while (s.hasNextLine()) {
fileContent.add(s.nextLine());
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return fileContent;
}
}