数组 - 稀疏数组的实现和相互转化【附源码】

(所有源码均在 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<String> 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
     * <p>
     * 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;
    }

    /**
     * 将稀疏数组转化为二维数组
     * <p>
     * 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
     * <p>
     * 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

ArrayUtil 类

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)));
    }
}

FileUtil 类

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<String> readFile(String path) {
        ArrayList<String> 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;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值