矩陣壓縮存儲


對稱矩陣的壓縮

實現原理

c二維數組存儲

在c中矩陣的表示是用二維數組。那么首先要搞清楚數組行列與矩陣行列的對應。在c語言中二維數組是按行存儲的。即順序存儲每一行。(第一行,第二行。。。最后一行)
看一下例子:

數組數量替換成arrs[i][j],方便說明。
int arrs[i][j] = {{1,2,3},
                  {1,2,3},
                  {1,2,3}};
//test 二維數組內存位置
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++){
        printf("%d\n",&arrs[i][j]);//內存位置連續
        }
    }

在上例中i表示有多少行,j 表示一行有多少列。剛好與矩陣的行列對應。

對稱矩陣

對稱矩陣是指元素以主對角線為對稱軸對稱,如demo代碼中的例子:

int arrs[row][col] = {
 {1,2,4},
 {2,1,5},
 {4,5,1}
 };

在上面的例子中元素以‘1’構成的對角線對稱,對於對稱矩陣的性質我們現在需要用的是 矩陣(i,j) == 矩陣(j,i);

壓縮原理

矩陣壓縮是將矩陣存儲於一位數組,以節約空間。那么根據矩陣(i,j) == 矩陣(j,i);我們就可以只存儲“矩陣(i,j)”了。當要訪問矩陣(j,i)時交換 i 和 j 就可以了。
那么怎么壓縮矩陣呢?,可以看出對於下面的例子中存儲上三角和下三角都可以,這里以存儲下三角為例。對於下面的矩陣我們只需要存儲對角線和其下面的元素。那么要存儲多少元素?或者一位數組要多大空間?來算一下:
在第一行需要存儲1個元素;在第二行需要存儲2個元素;在第三行需要存儲3個元素;則需要存儲1+2+3=6個元素。每行元素數量遞增1,遞增到n(n=行數)。那么推廣開存儲有n行的對稱矩陣需要的空間大小是:“1+2+3+…+n-1+n”= n(n+1)/2
現在可以壓縮存儲元素了。解壓矩陣參見下面的demo代碼。

{1,2,4},
{2,1,5},
{4,5,1}

完整實現代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define row 3
#define col 3

int *yasuo(int arrs[row][col]){
    int i,j, len = 0;
    int size = row*(row+1)/2;//n(n+1)/2
    int *arr = (int *)malloc(sizeof(int)*size);

     for(i = 0; i < row; i++){
         for(j = 0; j <= i; j++){
             arr[len++] = arrs[i][j];
         }
     }

     return arr;
}

//matrix test

void matrixTest(){
    int i, j, size =  row*(row+1)/2;//n(n+1)/2

    //對稱矩陣
    int arrs[row][col] = {
        {1,2,4},
        {2,1,5},
        {4,5,1}
    };


    //test 壓縮
    int *arr = yasuo(arrs);

     printf("test 壓縮\n");
    for(i = 0; i < size; i++){

        printf("%d\n",arr[i]);
    }

    printf("test 解壓縮\n");
    //test 解壓縮
    for(i = 0; i < row; i++){
         for(j = 0; j < col; j++){
            printf("%d\t",arr[getMatrix(arr,size,i,j)]);
         }
         printf("\n");
     }


}

//取元素
//參數解釋:int arr[]:壓縮后的一位數組; int length:數組長度 int i and int j:對應二維數組的下標
//返回元素在一維數組中的下標
int getMatrix(int arr[],int length,int i,int j){
    int len;
    if((i < 0 || i >= length) || (j < 0 || j >= length)){

        printf("Array Index Out Of Bounds\n");
        return -1;

    }
    if(i <= j){  
        //表示元素在下三角范圍

        len = i*(i+1)/2;    //計算第i行元素在一維數組中的起始位置
        len+=j;                 //起始位置 + 列偏移 j 就是元素(i,j)在一維數組中的位置
        return len;

    }else{
        //表示元素在上三角范圍

        //對於對稱矩陣,其上下三角的對稱元素的下標剛好相反,也就是說元素(i,j)== (j,i)
        //所以這里交換i和j的位置即可。

        len = j*(j+1)/2;    //計算第j行元素在一維數組中的起始位置
        len+=i;                 //起始位置 + 列偏移 i 就是元素(i,j)在一維數組中的位置
        return len;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM