Array和特殊数组的压缩

1. Array数组简介

当我们提到数组时,很多时候都说的是一维数组,一维数组是线性的,但数组本身并不是线性的,它包括二维,多维数组。

数组在内存中的分配是连续的,也就意味着你在创建它时就需要告诉内存它的容量(length)。这里我们用length表示,以和Java中的数组属性一致。length在java的数组中是固有属性,在一般情况下也是所以其他的数组实现是固有属性。

1.1 Array的数学表达

如果你擅长离散,你将会很乐意看见这样的表达方式

数据对象:

j 1 = 0 , . . . , b i − 1 , i = 1 , 2 , . . . , n , j_1 = 0,...,b_i-1,\quad i = 1,2,...,n, j1=0,...,bi1,i=1,2,...,n,

D = { a j 1 j 2 . . . j n ∣ n ( > 0 ) 称 为 数 组 的 维 度 , b 1 是 数 组 第 i 维 的 长 度 , j i 是 数 组 第 i 维 的 下 标 , a j 1 j 2 . . . j n ∈ E l e m S e t } D = \lbrace a_{{j_1}{j_2}...{j_n}}|n(>0)称为数组的维度,b_1是数组第i维的长度,j_i是数组第i维的下标,a_{{j_1}{j_2}...{j_n}} \in ElemSet \rbrace D={aj1j2...jnn(>0),b1ijii,aj1j2...jnElemSet}

数据关系:

R = { R 1 , R 2 , . . . , R n } R = \lbrace R1,R2,...,Rn \rbrace R={R1,R2,...,Rn}

R i = { ⟨ a j 1 . . . j i . . . j n , a j 1 . . . j i + 1 . . . j n ⟩ ∣ 0 ≤ j i ≤ b i − 2 , a j 1 . . . j i . . . j n , a j 1 . . . j i + 1 . . . j n ∈ D , i = 1 , 2 , . . . , n } Ri = \lbrace \langle a_{{j_1}...{j_i}...{j_n}},a_{{j_1}...{{j_i}+1}...{j_n}}\rangle|0 \leq j_i \leq b_i-2,\quad a_{{j_1}...{j_i}...{j_n}},a_{{j_1}...{{j_i}+1}...{j_n}} \in D,i=1,2,...,n \rbrace Ri={aj1...ji...jn,aj1...ji+1...jn0jibi2,aj1...ji...jn,aj1...ji+1...jnD,i=1,2,...,n}

在此进行一下上面公式的讲解(并不总会讲解):

数据对象:

我们用n来表示数组的维度,很显然n>0,n=0也意味着该数组是null,每一个个维度都有一个固有属性length,用 b i b_i bi表示,由此我们就可以定义一个索引来指向数组一个维度中的第 b i b_i bi 的位置,规定索引从0开始,那么其取值范围应该是 0 , . . . , b i − 1 0,...,b_i-1 0,...,bi1 ,那么怎么用索引在找到数据,n维数据需要n个索引来确定一个位置,这个是一个n元组。

数据关系:

那么数据关系又是怎么样的,不擅长离散的人可能比较难理解上面的公式,其实它的关系就是,n个线性数据结构关系的集合。在每一个维度内都是线性的数据结构。更直观一些,确定n-1个不同维的索引值后,即将n维降为1维,呈现的是线性数据结构。

1.2 数组的基本操作

  • InitArray(初始化)
  • DestoryArray(销毁)
  • Value(取值)
  • Assgin(赋值)

在这儿仅提一下,因为高级语言(包括C)都有对数组的支持。

当你使用汇编,写单片机,嵌入式的程序时,可能需要考虑这样的问题,这时你将会考虑内存地址,寄存器标志位,串口等问题。你可能会需要开辟一个内存区域去存放一些必要的数据,该内存区域可能就使用到数组结构。

2. 矩阵压缩

矩阵即对应了二维数组,但仍然稍微有些不一样,数组是索引是从0开始的。

我们看两个场景:

  1. 想一想无平行变的无向图用邻接矩阵的方式表示是什么样的?(随手画了一个)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RE6EW6t5-1576982859934)(./resources/image/01/01-2.jpg)]

  2. 你会怎样保存一个这样的棋局?
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JAs6tC8T-1576982859936)(./resources/image/01/01-1.jpg)]

2.1 对称矩阵

看第一个问题,我们用邻接矩阵表示一下看看,如下
[ 0 1 1 1 0 1 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1 0 1 ] (1) \left[ \begin{matrix} 0 & 1 & 1 & 1 & 0 \\ 1 & 0 & 0 & 0 & 1 \\ 1 & 0 & 0 & 1 & 1 \\ 1 & 0 & 1 & 0 & 0 \\ 0 & 1 & 1 & 0 & 1 \end{matrix} \right] \tag{1} 0111010001100111010001101(1)

很容易看出来这是一个对称矩阵,即满足
a i j = a j i 1 ≤ i , j ≤ n a_{ij}= a_{ji} \quad 1 \leq i,j \leq n aij=aji1i,jn

故我们可以将 n 2 n^2 n2个元压缩到 n ( n + 1 ) / 2 n(n+1)/2 n(n+1)/2个元(感兴趣的可以自己算一下)

我们可以进一步将二维数组存储压缩为一维数组存储 s a [ n ( n + 1 ) / 2 ] sa[n(n+1)/2] sa[n(n+1)/2]来存储, s a [ k ] sa[k] sa[k] a i j a_{ij} aij存在一一对应的关系

k = { i ( i − 1 ) / 2 + j − 1 i ≥ j j ( j − 1 ) / 2 + i − 1 j < i (1-1) k=\begin{cases} i(i-1)/2+j-1 && i \geq j \\ j(j-1)/2+i-1 && j < i \end{cases} \tag{1-1} k={i(i1)/2+j1j(j1)/2+i1ijj<i(1-1)

上述是把矩阵当作矩阵来看,矩阵描述中没有第0行,从第1行开始,在程序往往使用二维数组来存储矩阵,故第一行的索引为0。我们真正使用的索引转换如下:

k = { i ( i + 1 ) / 2 + j i ≥ j j ( j + 1 ) / 2 + i j < i (1-2) k=\begin{cases} i(i+1)/2+j && i \geq j \\ j(j+1)/2+i && j < i \end{cases} \tag{1-2} k={i(i+1)/2+jj(j+1)/2+iijj<i(1-2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7u4PR2J-1576982859937)(./resources/image/01/01-3.png)]

压缩代码实现:

package xin.ajay.utils;

import javax.xml.crypto.Data;
import java.util.Arrays;

/*
  Two-dimensional array
  二维数组工具
 */
public class TwoDimArrayUtils {

    /**
     * 该方法用于 {@code int} 型对称二维数组的压缩.
     *
     * @param arr 待压缩的对称二维数组
     *
     * @return 压缩完成的一维数组
     */
    public static int[] compressSymmetricArrays(int[][] arr){
        //1.获取arr数组长度
        int length = arr.length;
        //2. 获取压缩后的数组长度
        int len =length*(length+1)/2;
        //3. 创建一维数组
        int[] compressed = new int[len];
        //4. 将二维数组压缩为一维数组
        for (int i = 0; i < length; i++) {
            System.arraycopy(arr[i], 0, compressed, ((i + 1) * i)/ 2, i + 1);
        }

        return compressed;
    }
    
	 /**
     * 该方法用于 {@code int} 型对称二维数组的解压缩.
     * 
     * @param compressedArr  需要解压为二维对称数组的一维数组
     * @return 二维对称数组
     */
    public static int[][] decompressSymmetricArrays(int[] compressedArr){
        int length = compressedArr.length;
        //1. 计算出原数组的n
        int len = ((int)Math.sqrt(length * 8 + 1)-1)/2;

        //2. 创建原数组
        int[][] decompressedArr = new int[len][len];

        int i = 0;
        //3. 遍历压缩数组解压
        for (int k = 0; k < compressedArr.length; k++) {
            if(k > i * (i + 1) / 2 + i){
                i++;
            }
            decompressedArr[i][k-i*(i+1)/2] = compressedArr[k];
            decompressedArr[k-i*(i+1)/2][i] = compressedArr[k];
        }

        return decompressedArr;

    }
    
	//test
    public static void main(String[] args) {
        int[][] integers = new int[][]{{0,1,3,6},
                                       {1,2,4,7},
                                       {3,4,5,8},
                                       {6,7,8,9}};
        int[] compressedArr = TwoDimArrayUtils.compressSymmetricArrays(integers);
        int[][] decompressedArr = TwoDimArrayUtils.decompressSymmetricArrays(compressedArr);

        System.out.println("---------压缩前:");
        for (int[] i : integers) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();
        
        System.out.println("--------压缩后:");
        System.out.println(Arrays.toString(compressedArr));
		System.out.println();
        
        System.out.println("---------解压缩后:");
        for (int[] i : decompressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();


    }

}

输出结果:

---------压缩前:
[0, 1, 3, 6]
[1, 2, 4, 7]
[3, 4, 5, 8]
[6, 7, 8, 9]

--------压缩后:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

---------解压缩后:
[0, 1, 3, 6]
[1, 2, 4, 7]
[3, 4, 5, 8]
[6, 7, 8, 9]

2.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 0 1 0 1 0 0 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 2 0 0 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 ] (2) \left[ \begin{matrix} 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 & 0 & 1 & 0 & 1 & 0 & 0 & 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 & 2 & 0 & 0 & 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\\ \end{matrix} \right] \tag{2} 000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000102000000000000020000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(2)

该数组大部分都是相同的都为0,可以进行稀疏数组的压缩。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8O6XWQvn-1576982859941)(.\resources\image\01\01-4.png)]

原数组含 n 2 n^2 n2 个单位空间,压缩后,只需要 ( v a l u e . n u m + 1 ) ∗ 3 (value.num+1)*3 (value.num+1)3 个单位空间。稀疏数组的第0行存放的分别是原数组的行数、列数和有效数据个数。后存放的是原数组第i行,第j列的值。

代码实现,包含压缩和解压缩:

package xin.ajay.utils;

import java.util.Arrays;

/*
  Two-dimensional array
  二维数组工具
 */
public class TwoDimArrayUtils {

    /**
     *  该方法用于 {@code int} 型二维疏数组的压缩.
     *  默认 0 为数组中出现的大多少数据。
     *
     * @param arr 一个二维数组
     * @return 压缩后的二维数组
     */
    public static int[][] compressSparseArrays(int[][] arr){
       return compressSparseArrays(arr,0);
    }

    /**
     *  该方法用于 {@code int} 型二维稀疏数组的压缩.
     *
     * @param arr  一个二维数组
     * @param d  数组中出现的大多数数据,一般为填充的无效数据0
     * @return 压缩后的二维数组
     */
    public static int[][] compressSparseArrays(int[][] arr,int d){
        //非d的数量
        int sum =0;

        //1. 得到非d的数量
        for (int[] a : arr) {
            for (int num : a) {
                if (num != d) sum++;
            }
        }

        //2. 创建稀疏数组
        int[][] sparesArr = new int[sum + 1][3];
        sparesArr[0][0] = arr.length;
        sparesArr[0][1] = arr[0].length;
        sparesArr[0][2] = sum;

        int count=0;
        //3. 将二维数组中的有效数据存入到稀疏数组中
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if(arr[i][j]!=d){
                    count++;
                    sparesArr[count][0] = i;
                    sparesArr[count][1] = j;
                    sparesArr[count][2] = arr[i][j];
                }
            }
        }

        return sparesArr;
    }

    /**
     * 解压缩 {@code int} 稀疏数组.
     * 默认 0 为原数组中出现的大多少数据。
     *
     * @param compressedArr 需要解压的稀疏数组
     * @return 解压后的二维数组
     */
    public static int[][] decompressSparseArrays(int[][] compressedArr){
        return decompressSparseArrays(compressedArr,0);
    }

    /**
     * 解压缩 {@code int} 稀疏数组.
     *
     * @param compressedArr  需要被解压的二维数组
     * @param d 原二维数组中的大多数数据,一般为无效的数据0
     * @return 解压后的二维数组
     */
    public static int[][] decompressSparseArrays(int[][] compressedArr,int d){

        int sum = compressedArr[0][2];

        //1. 创建二维数组,并初始化
        int[][] decompressedArr = new int[compressedArr[0][0]][compressedArr[0][1]];

        if(d!=0){
            for (int i = 0; i < decompressedArr.length; i++) {
                for (int j = 0; j < decompressedArr[i].length; j++) {
                    decompressedArr[i][j] = d;
                }
            }
        }

        //2. 遍历稀疏数组
        for (int i = 1; i <= sum; i++) {
            decompressedArr[compressedArr[i][0]][compressedArr[i][1]] = compressedArr[i][2];
        }

        return decompressedArr;
    }
	
    //test
    public static  void main(String[] args) {
        int[][] integers = new int[15][15];

        integers[6][6] =1;
        integers[6][8] =1;
        integers[7][7] =2;
        integers[8][6] =2;
        integers[9][5] =2;
        int[][] compressedArr = TwoDimArrayUtils.compressSparseArrays(integers);
        int[][] decompressedArr = TwoDimArrayUtils.decompressSparseArrays(compressedArr);

        System.out.println("---------压缩前:");
        for (int[] i : integers) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

        System.out.println("--------压缩后:");

        for (int[] i : compressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

        System.out.println("--------解压后");
        for (int[] i : decompressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

    }

}

结果显示:

---------压缩前:
[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, 0, 1, 0, 1, 0, 0, 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, 2, 0, 0, 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]

--------压缩后:
[15, 15, 5]
[6, 6, 1]
[6, 8, 1]
[7, 7, 2]
[8, 6, 2]
[9, 5, 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, 0, 1, 0, 1, 0, 0, 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, 2, 0, 0, 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]

最后附上以上所有的代码:

package xin.ajay.utils;

import java.util.Arrays;

/**
 *  Two-dimensional array
 *  二维数组工具
 * 
 * 2019/12/9
 *
 * @author AjayZeng
 */
public class TwoDimArrayUtils {

    /**
     * 该方法用于对称二维数组的压缩.
     * 此处的对称数组使用的是对称矩阵的概念。将对称 n维的二维对称数组压缩为一维数组。
     *
     * @deprecated 没有实用价值,也未经过测试,不使用
     * @param arr 待压缩的对称二维数组
     *
     * @param <T> 数组存放的被压缩的的对象类型.
     *           新生成的一维数组没有对 T 进行克隆,只是将 T 的引用值放在了一个新的数组中
     * @return  被压缩成为一维数组
     */
    public static <T> T[] compressSymmetricArrays(T[][] arr) {
        int length = arr.length;
        int len = length * (length + 1) / 2;
        @SuppressWarnings("unchecked") T[] compressed = (T[]) new Object[len];

        for (int i = 0; i < length; i++) {
            System.arraycopy(arr[i], 0, compressed, ((i + 1) * i) / 2, i + 1);
        }
        return compressed;
    }



    /**
     * 该方法用于 {@code int} 型对称二维数组的压缩.
     *
     * @param arr 待压缩的对称二维数组
     *
     * @return 压缩完成的一维数组
     */
    public static int[] compressSymmetricArrays(int[][] arr){
        //1.获取arr数组长度
        int length = arr.length;
        //2. 获取压缩后的数组长度
        int len =length*(length+1)/2;
        //3. 创建一维数组
        int[] compressed = new int[len];
        //4. 将二维数组压缩为一维数组
        for (int i = 0; i < length; i++) {
            System.arraycopy(arr[i], 0, compressed, ((i + 1) * i)/ 2, i + 1);
        }

        return compressed;
    }

    /**
     * 该方法用于 {@code int} 型对称二维数组的解压缩.
     *
     * @param compressedArr  需要解压为二维对称数组的一维数组
     * @return 二维对称数组
     */
    public static int[][] decompressSymmetricArrays(int[] compressedArr){
        int length = compressedArr.length;
        //1. 计算出原数组的n
        int len = ((int)Math.sqrt(length * 8 + 1)-1)/2;

        //2. 创建原数组
        int[][] decompressedArr = new int[len][len];

        int i = 0;
        //3. 遍历压缩数组解压
        for (int k = 0; k < compressedArr.length; k++) {
            if(k > i * (i + 1) / 2 + i){
                i++;
            }
            decompressedArr[i][k-i*(i+1)/2] = compressedArr[k];
            decompressedArr[k-i*(i+1)/2][i] = compressedArr[k];
        }

        return decompressedArr;

    }


    /**
     *  该方法用于 {@code int} 型二维疏数组的压缩.
     *  默认 0 为数组中出现的大多少数据。
     *
     * @param arr 一个二维数组
     * @return 压缩后的二维数组
     */
    public static int[][] compressSparseArrays(int[][] arr){
       return compressSparseArrays(arr,0);
    }

    /**
     *  该方法用于 {@code int} 型二维稀疏数组的压缩.
     *
     * @param arr  一个二维数组
     * @param d  数组中出现的大多数数据,一般为填充的无效数据0
     * @return 压缩后的二维数组
     */
    public static int[][] compressSparseArrays(int[][] arr,int d){
        //非d的数量
        int sum =0;

        //1. 得到非d是数量
        for (int[] a : arr) {
            for (int num : a) {
                if (num != d) sum++;
            }
        }

        //2. 创建稀疏数组
        int[][] sparesArr = new int[sum + 1][3];
        sparesArr[0][0] = arr.length;
        sparesArr[0][1] = arr[0].length;
        sparesArr[0][2] = sum;

        int count=0;
        //3. 将二维数组中的有效数据存入到稀疏数组中
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if(arr[i][j]!=d){
                    count++;
                    sparesArr[count][0] = i;
                    sparesArr[count][1] = j;
                    sparesArr[count][2] = arr[i][j];
                }
            }
        }

        return sparesArr;
    }

    /**
     * 解压缩 {@code int} 稀疏数组.
     * 默认 0 为原数组中出现的大多少数据。
     *
     * @param compressedArr 需要解压的稀疏数组
     * @return 解压后的二维数组
     */
    public static int[][] decompressSparseArrays(int[][] compressedArr){
        return decompressSparseArrays(compressedArr,0);
    }

    /**
     * 解压缩 {@code int} 稀疏数组.
     *
     * @param compressedArr  需要被解压的二维数组
     * @param d 原二维数组中的大多数数据,一般为无效的数据0
     * @return 解压后的二维数组
     */
    public static int[][] decompressSparseArrays(int[][] compressedArr,int d){

        int sum = compressedArr[0][2];

        //1. 创建二维数组,并初始化
        int[][] decompressedArr = new int[compressedArr[0][0]][compressedArr[0][1]];

        if(d!=0){
            for (int i = 0; i < decompressedArr.length; i++) {
                for (int j = 0; j < decompressedArr[i].length; j++) {
                    decompressedArr[i][j] = d;
                }
            }
        }

        //2. 遍历稀疏数组
        for (int i = 1; i <= sum; i++) {
            decompressedArr[compressedArr[i][0]][compressedArr[i][1]] = compressedArr[i][2];
        }

        return decompressedArr;
    }
    
    
	//测试整型对称数组的压缩
    public static void main(String[] args) {
        int[][] integers = new int[][]{{0,1,3,6},
                                       {1,2,4,7},
                                       {3,4,5,8},
                                       {6,7,8,9}};
        int[] compressedArr = TwoDimArrayUtils.compressSymmetricArrays(integers);
        int[][] decompressedArr = TwoDimArrayUtils.decompressSymmetricArrays(compressedArr);

        System.out.println("---------压缩前:");
        for (int[] i : integers) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

        System.out.println("--------压缩后:");
        System.out.println(Arrays.toString(compressedArr));
        System.out.println();

        System.out.println("---------解压缩后:");
        for (int[] i : decompressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();


    }

/*  //测试整型稀疏数组
	public static  void main(String[] args) {
        int[][] integers = new int[15][15];

        integers[6][6] =1;
        integers[6][8] =1;
        integers[7][7] =2;
        integers[8][6] =2;
        integers[9][5] =2;
        int[][] compressedArr = TwoDimArrayUtils.compressSparseArrays(integers);
        int[][] decompressedArr = TwoDimArrayUtils.decompressSparseArrays(compressedArr);

        System.out.println("---------压缩前:");
        for (int[] i : integers) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

        System.out.println("--------压缩后:");

        for (int[] i : compressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

        System.out.println("--------解压后:");
        for (int[] i : decompressedArr) {
            System.out.println(Arrays.toString(i));
        }
        System.out.println();

    }*/

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值