在c中矩陣的表示是用二維數組。那麼首先要搞清楚數組行列與矩陣行列的對應。在c語言中二維數組是按行存儲的。即順序存儲每一行。(第一行,第二行。。。最後一行)
看一下例子:css
數組數量替換成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代碼中的例子:markdown
int arrs[row][col] = {
{1,2,4},
{2,1,5},
{4,5,1}
};
在上面的例子中元素以‘1’構成的對角線對稱,對於對稱矩陣的性質咱們如今須要用的是 矩陣(i,j) == 矩陣(j,i);ui
矩陣壓縮是將矩陣存儲於一位數組,以節約空間。那麼根據矩陣(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代碼。spa
{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;
}
}