Java實現普通二維陣列和稀疏陣列的相互轉換

weixin_47219685發表於2020-09-25

稀疏陣列應用場景

​ 在五子棋遊戲當中,一般都有“存檔”和“繼續上局”的功能,存檔的時候需要把棋盤上的資料轉成二維陣列,儲存到磁碟中,繼續上局的時候需要把資料從磁碟中取出來,還原到棋盤上。

在這裡插入圖片描述

​ 我們發現,這個二維陣列很多資料都是0,有效資料只有4個(1,2,1,2),這樣直接儲存會浪費磁碟空間,這時候需要將資料壓縮為稀疏陣列來節省空間。

稀疏陣列格式

為了對比學習,我們先初始化一個原始二維陣列,模擬棋盤

int[][] initialArray = {
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    ,{0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0}
    ,{0,0,0,0,1,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,0}
    ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}    
};

​ 稀疏陣列也是一個二維陣列,定義格式與普通二維陣列一樣,略有不同的是稀疏陣列只有3列。稀疏陣列的行數為:原始陣列的有效的資料的數量+1。

int[][] sparseArray = new int[][3];

二維陣列轉稀疏陣列

​ 稀疏陣列的第一行第一個資料是原始二維陣列的行數,第一行第二個資料是原始二維陣列的列數,第一行第三個資料是原始二維陣列的有效資料個數。

sparseArray[0][0] = initialArray.length;
sparseArray[0][0] = initialArray[0].length;
// 計算原始陣列中有效的資料的數量
int effectiveDataNum = 0;
for (int i = 0; i < initialArray.length; i++) {
    for (int j = 0; j < initialArray[i].length; j++) {
        if (initialArray[i][j] != 0) {
            effectiveDataNum ++;
        }
    }
}
sparseArray[0][3] = effectiveDataNum ;

​ 從第二行開始,第一個資料是二維陣列有效資料的縱座標,第二個資料是二維陣列有效資料的橫座標,第三個資料是二維陣列有效資料的值。

//2、迴圈往稀疏陣列中賦值
// 由於稀疏陣列第一行已經有資料了,所以是從第二行開始插入
int index = 1;
for (int i = 0; i < initialArray.length; i++) {
    for (int j = 0; j < initialArray[i].length; j++) {
        if (arraya[i][j] != 0) {
            sparseArray[index][0] = i;
            sparseArray[index][1] = j;
            sparseArray[index][2] = arraya[i][j];
            index++;
        }
    }
}

​ 這樣一個二維陣列就已經成功的轉為了一個稀疏陣列,我們輸出一下看看稀疏陣列的資料。

// 4.輸出稀疏陣列
System.out.println("得到的稀疏陣列:");
for (int i = 0; i < sparseArray.length; i++) {
    for (int j = 0; j < sparseArray[i].length; j++) {
        System.out.print(sparseArray[i][j]+"  ");
    }
    System.out.println();
}

// 輸出結果如下:
/*
得到的稀疏陣列:
15 15 4 
5 4 1 
6 4 1 
6 5 2 
7 4 2 

*/

稀疏陣列轉二維陣列

​ 能從二維陣列轉成稀疏陣列,也要能從稀疏陣列轉成二維陣列,轉換方法如下:

//稀疏陣列轉為原始陣列
int[][] arrayb = new int[sparseArray[0][0]][sparseArray[0][1]];
for (int i = 1; i < sparseArray.length; i++) {
    arrayb[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}

// 我們輸出一下轉化後的陣列
for (int i = 0; i < arrayb.length; i++) {
    for (int j = 0; j < arrayb[i].length; j++) {
        System.out.print(arrayb[i][j]+" ");
    }
    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 1 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 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 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
*/

個人思考

​ 這部分是我學習了稀疏陣列之後的想法,歡迎大家來碰撞。

​ 稀疏陣列每行的第一個資料是存放有效資料的列數,第二個資料是存放有效資料的行數,那能不能將兩個資料簡化為一個 儲存有效資料在二維陣列中是第幾個數呢?以一個11*11的二維陣列為例,總共11*11 = 121個資料,那是否可以給這個陣列裡面的資料從0-120編號呢,這樣稀疏陣列就只用存放兩列資料了。第一列為有效資料的編號,第二列為稀疏陣列的值?仍以開始建立的原始二維陣列為例:

/*
	initialArray[1][6]的值為1,對應在稀疏資料裡就是
	sparseArray[1][0] = 1
	sparseArray[1][1] = 6
	sparseArray[1][2] = 1
	由於initialArray[1][6]是該二維資料的第 1*11+6+1 = 18個資料,那能不能在稀疏資料中只存放一個編號18,和一個值1呢。這樣稀疏資料又可以減少一列,相比於普通稀疏陣列又節省了月三分之一的空間了。
*/

​ 最後,初次寫部落格,如果錯誤的地方歡迎大佬指出,謝謝!

​ 總的程式碼如下:

package chengquan.dataStru;
/*
chengquan 20200925 稀疏陣列與二維陣列的相互轉化
 */
public class SparseArray {
    public static void main(String[] args) {
        // 1.先自定義一個二維陣列 0表示沒有棋子,1表示黑子,2表示藍子
        int[][] initialArray = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                        ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                        ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                        ,{0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0}
                        ,{0,0,0,0,1,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,0}
                        ,{0,0,0,0,0,0,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.準備轉成稀疏陣列
            // 1、先計算出來原始陣列中有多少有效值
        int count = 0;
        for (int i = 0; i < initialArray.length; i++) {
            for (int j = 0; j < initialArray[i].length; j++) {
                if (initialArray[i][j] != 0) {
                    count++;
                }
            }
        }
            // 2、原始陣列有多少行多少列
        int row = initialArray.length;
        int col = initialArray[0].length;
        //3.建立稀疏數字
        int[][] sparseArray = new int[count+1][3];
            //1、給稀疏陣列賦值 第一行第一個資料是原始二維陣列的行數,
            // 第一行第二個資料是原始二維陣列的列數,
            // 第一行第三個資料是原始二維陣列的有效資料個數
        sparseArray[0][0] = row;
        sparseArray[0][1] = col;
        sparseArray[0][2] = count;
            //2、迴圈往稀疏陣列中賦值 從第二行開始,
            // 第一個資料是二維陣列有效資料的縱座標,
            // 第二個資料是二維陣列有效資料的橫座標,
            // 第三個資料是二維陣列有效資料的值。
        int index = 1;
        for (int i = 0; i < initialArray.length; i++) {
            for (int j = 0; j < initialArray[i].length; j++) {
                if (initialArray[i][j] != 0) {
                    sparseArray[index][0] = i;
                    sparseArray[index][1] = j;
                    sparseArray[index][2] = initialArray[i][j];
                    index++;
                }
            }
        }
        // 4.輸出稀疏陣列
        System.out.println("得到的稀疏陣列:");
        for (int i = 0; i < sparseArray.length; i++) {
            for (int j = 0; j < sparseArray[i].length; j++) {
                System.out.print(sparseArray[i][j]+" ");
            }
            System.out.println();
        }

        // 5.稀疏陣列轉為原始陣列
        int[][] arrayb = new int[sparseArray[0][0]][sparseArray[0][1]];
        for (int i = 1; i < sparseArray.length; i++) {
                arrayb[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        // 輸出看看
        for (int i = 0; i < arrayb.length; i++) {
            for (int j = 0; j < arrayb[i].length; j++) {
                System.out.print(arrayb[i][j]+" ");
            }
            System.out.println();
        }
    }
}

相關文章