稀疏数组

概述

  稀疏数组是指那些零元个数远大于非零元个数的数组,而稀疏数组的零元分布往往没有规律可循。最经典的例子就是棋盘,在保存棋局时,棋盘上棋子的数目往往不会布满整个棋盘。以中国象棋为例,棋盘为10*9,而棋子数为32,而且在走棋过程中还会减少棋子数。所以如果用整个数组来保存棋盘就会花费太多空间。这时就要对稀疏数组进行压缩存储。

  压缩存储的处理方法是:

  1. 创建一个小规模的二维数组,其列数为3,分别记录行、列、值。

  2. 第一行记录原数组的行数、列数,以及非零元个数。

  3. 之后每一行记录每一个非零元在原数组中的行位标、列位标和值。

  以这个棋盘为例:

  

  用两位数表示一个棋子:

  1. 个位数:1表示兵、卒;2表示炮、砲;3表示车;4表示马;5表示相、象;6表示仕、士;7表示帅、将。

  2. 十位数:1表示红方;2表示黑方。

  比如,黑方用2表示,将用7表示,所以黑方的将用27表示;红方用1表示,兵用1表示,所以红方的兵用11表示。

  用一个10*9的二维数组存储棋盘,则这个棋盘可以表示为:

  

  即二维数组board中,board[1][3]=27,board[1][4]=26,board[1][5]=11,board[2][2]=11,board[2][5]=26,board[8][4]=17。

  对该二维数组进行压缩:

  1. 一共需要存储6个棋子,所以压缩后数组为sparseBoard[7][3]。

  2. 第一行存储二维数组的行数、列数和棋子数,即sparseBoard[0]=10,sparseBoard[1]=9,sparseBoard[2]=6。

  3. 之后6条记录分别存取棋子。

  最终得到的结果为:

  

代码实现

  压缩稀疏数组:

 1 public static int[][] compress(int[][] arr) {
 2     if (arr == null) return null;
 3     // 行数
 4     int m = arr.length;
 5     // 列数
 6     int n = arr[0].length;
 7     // 非零元个数
 8     int num = 0;
 9     for (int i = 0; i < m; i++) {
10         for (int j = 0; j < n; j++) {
11             if (arr[i][j] != 0) {
12                 num++;
13             }
14         }
15     }
16     // 创建压缩后的数组,列数为3,行数为1+非零元个数
17     int[][] cArr = new int[1 + num][3];
18     // 第一行记录原数组的行数、列数,以及非零元个数
19     cArr[0][0] = m;
20     cArr[0][1] = n;
21     cArr[0][2] = num;
22     // 每一行记录每一个非零元在原数组中的行位标、列位标和值
23     for (int i = 0, k = 1; i < m; i++) {
24         for (int j = 0; j < n; j++) {
25             if (arr[i][j] != 0) {
26                 cArr[k][0] = i;
27                 cArr[k][1] = j;
28                 cArr[k][2] = arr[i][j];
29                 k++;
30             }
31         }
32     }
33     return cArr;
34 }
compress

  将压缩后的数组还原为稀疏数组:

 1 public static int[][] recovery(int[][] cArr) {
 2     if (cArr == null || cArr[0].length != 3) return null;
 3     // 第一行的前两个单元存储了原二维数组的行数和列数
 4     int[][] arr = new int[cArr[0][0]][cArr[0][1]];
 5     // 将除第一行外每一行还原到二维数组中,每一行的前两个单元为行位标和列位标,第三个单元为元素值
 6     for (int i = 1; i <= cArr[0][2]; i++) {
 7         arr[cArr[i][0]][cArr[i][1]] = cArr[i][2];
 8     }
 9     return arr;
10 }
recovery

  测试:

  

  

  

原文地址:https://www.cnblogs.com/lqkStudy/p/11505790.html