順序表練習(三) 對稱矩陣的壓縮儲存

2021-10-02 03:08:56 字數 3516 閱讀 6660

本次練習的內容是對稱矩陣的壓縮儲存以及各種配套函式的實現,先放一下對稱矩陣的定義:

對於乙個方陣a,若其中的元素對稱矩陣。通俗地理解,對稱矩陣就是沿著主對角線(「\」這樣的是主對角線)將矩陣摺疊後對應元素相同的矩陣。

對稱矩陣裡有近一半的元素是相同的,如果對其進行壓縮儲存,我們就能省下近一半的空間。

實現對稱矩陣的壓縮儲存

實現相應的初始化、銷毀、列印矩陣等函式

實現對壓縮後的矩陣的值的修改

首先先定義乙個結構體:

#define dimsize 5

typedef struct symmetricmatrix

} mat;

取別名為mat型別,其中dim意為方陣的維度,即表示為dim*dim階方陣。建構函式裡簡單地做了一下初始化,另外,我們約定矩陣以行優先形式儲存,並且儲存下三角的元素+主對角線上的元素。

//建立mat,其中陣列的大小根據公式計算得出

mat *createmat()

; return mat;

}//銷毀mat同時以引用形式將指標置空

void destroymat(mat *&mat)

//獲取實際的陣列長度,根據公式計算得出

int getarraysize(mat *mat)

//輸出陣列,做了一些簡單的格式處理

void printarr(mat *mat)

cout << "] " << sz << endl;

}//為後面檢查行列是否合法準備

bool checkindex(mat *mat, int col, int row)

其中值得一提的是計算陣列大小的公式 dim*(dim+1)/2,看上面給的紅格仔示意圖,如果我們將每行的紅色格仔數量標出來,就能得到乙個1 2 3 4 5的數列,根據高中的等差數列求和公式,化簡後就可以得到dim*(dim+1)/2,這就是求壓縮後的矩陣的實際陣列長度的公式

實現的是根據傳進來的n*n大小的陣列matrix來初始化壓縮矩陣mat的函式,上**:

void initmat(mat *mat, int *matrix)

引數中的matrix指標實際上是乙個n*n大小的矩陣陣列,這裡為了方便直接使用了一維陣列,其實按常規思維的話要用二維陣列來表示矩陣。

這幾行**的核心思路是遍歷傳進來的陣列,將下三角+主對角線上的元素存進陣列裡。其中k代表mat中陣列的下標,i*n+j是用來分割陣列的,因為傳進來的是用一維陣列儲存的矩陣,i為行數j為列數。

除此之外,第二層迴圈的條件j < i+1是根據情況優化的,因為對於矩陣壓縮而言,每行只儲存和行數相同數量的元素,同時考慮到陣列下標是從0開始,所以這裡就寫成j先上**:

int getvalue(mat *mat, int col, int row) //columns and rows are logical index (based-1)

**中寫了一些英文注釋幫助理解。引數中的col和row就是要取的值的列號和行號,是從1開始的;checkindex在上面輔助函式裡有,不再贅述。重點解釋一下第二個if和i的計算:

1.函式中第二個if是為了應對取上三角元素的情況(列號大於行號,即是上三角元素),因為在陣列中我們沒有存上三角元素,所以這裡需要繞個彎,利用對稱矩陣的特性(其實這就是為何能壓縮的原因)將行列號互換就變成了取下三角元素,就可以直接在陣列裡取值。

2.i的計算其實也是和之前算陣列長度的原理差不多,不過這裡的引數是從1開始的行列號,所以要同時把邏輯下標轉成物理下標才行。如果不用轉換成物理下標的話,我們的公式應該是這樣的i = row*(row+1)/2 + col,大概的原理就是先計算當前元素上面有多少行的元素,再加上當前行的當前元素前面有多少個元素,加起來就能得到當前元素在陣列的位置。但是現在我們需要轉換成物理下標,所以就要把行號和列號都減1,公式就變成了i = row*(row-1)/2 + col - 1

如果還是不能理解的話推薦自行畫圖並結合等差數列求和公式推導一遍。

因為有了上面實現的getvalue函式,列印矩陣的函式很快就能寫出來:

void printmat(mat *mat)

}

注意getvalue接收的行列號是邏輯下標,即從1開始。

根據上面的公式,我們很快就能實現這個函式:

void value(mat *mat, int val, int col, int row)

要注意的是如果我們修改乙個主對角線以外的元素,會同時修改他對稱的另乙個元素,即修改a12會同時修改a21。

給了main函式和測試的樣例,直接執行即可。

#include using namespace std;

#define dimsize 5

typedef struct symmetricmatrix

} mat;

mat *createmat()

; return mat;

}void destroymat(mat *&mat)

int getarraysize(mat *mat)

void printarr(mat *mat)

cout << "] " << sz << endl;

}bool checkindex(mat *mat, int col, int row)

void initmat(mat *mat, int *matrix)

int getvalue(mat *mat, int col, int row) //columns and rows are logical index (based-1)

void value(mat *mat, int val, int col, int row)

void printmat(mat *mat)

}int main()

; initmat(mat, arr);

printarr(mat);

printmat(mat);

cout << endl;

value(mat, 99, 4, 1);

printmat(mat);

destroymat(mat);

return 0;

}

對稱矩陣的壓縮的實現難度比較小,重難點在於下標的計算,下標的計算公式用到了等差數列的求和公式。萬丈高樓平地起,越是基礎的東西越需要多打多練。

實驗四 2 對稱矩陣的壓縮儲存

1.實驗目的 1 掌握對稱矩陣的壓縮儲存方法 2 驗證對稱矩陣壓縮儲存的定址方法。2.實驗內容 1 建立乙個nxn的對稱矩陣a 2 將對稱矩陣用一維陣列sa儲存 3 在陣列sa中對矩陣a的任意元素進行定址操作。3.實驗程式 由於程式較為簡單,只需直接建立乙個工程,然後再在工程裡新建乙個源程式檔案即可...

第八周專案三 對稱矩陣壓縮儲存的實現與應用 1

檔名稱 對稱矩陣壓縮儲存的實現與應用 1 作 者 胡德傑 完成日期 2017年10月30號 版 本 號 v1.1.20 include include define n 4 void init int b 初始化 int value int b,int i,int j 返回儲存在b m 中,對應二維...

第九周 對稱矩陣壓縮儲存的實現

all right reserved.date 2015年10月26日 版本 v1.0.1 作業系統 xp 執行環境 vc6.0 問題描述 對稱矩陣壓縮儲存的實現 用壓縮形式儲存對稱矩陣,實現下面的操作並測試 void init int b 為n階對稱矩陣初始化儲存資料的一維陣列b int valu...