1. 程式人生 > >三元組建立矩陣 一次定位快速轉置 矩陣的加法、減法、乘法

三元組建立矩陣 一次定位快速轉置 矩陣的加法、減法、乘法

首先說說我們經常見到或者使用的矩陣:
(1):三角矩陣:對角線一側的元素沒有限制,另一側全為0或者常數c。常見的有上三角矩陣和下三角矩陣。
(2):對角矩陣:對角矩陣是指有效元素集中在對角線兩側,我們常用的三對角矩陣來將矩陣的壓縮。三對角矩陣指的是三條對角線以外的元素均為0。
(3):稀疏矩陣:指的是矩陣中非零元素的個數低於矩陣中元素總個數的%25。
正是因為稀疏矩陣的這個性質,我們才可以將稀疏矩陣儲存到一個三元組中,之後再進行轉置等操作。
下面附上程式碼:

#include<stdio.h>

#define MAXSIZE 100

typedef struct
{
    int row;    //相當於x 
    int col;    //相當於y
    int value;  //求值
}Triple
; typedef struct { Triple data[MAXSIZE]; //定義大小為100,表示稀疏矩陣中最多存在100個有效元素 int rows; //稀疏矩陣的總行數 int cols; //稀疏矩陣的總列數 int numbers; //非零元素的總數 }TSMatrix; void InitTSM(TSMatrix *); void ShowMatrix(TSMatrix); void Transpose_rowsadd(TSMatrix *); void Transpose_coladd(TSMatrix
*); void Transpose_once(TSMatrix *); void AddMatrix(TSMatrix *,TSMatrix *); void MultiMatrix(TSMatrix,TSMatrix); void ChangeToMatrix(TSMatrix TSM,int [TSM.rows+1][TSM.cols+1]); void ChangeToMatrix(TSMatrix TSM,int matrix[TSM.rows+1][TSM.cols+1]) { int i,j; for(i = 1;i <= TSM.rows;i++) { for(j = 1
;j <= TSM.cols;j++) { matrix[i][j] = 0; } } for(i = 1;i <= TSM.numbers;i++) { matrix[TSM.data[i].row][TSM.data[i].col] = TSM.data[i].value; } } void MultiMatrix(TSMatrix TSM1,TSMatrix TSM2) { if(TSM1.cols != TSM2.rows) { printf("矩陣格式不匹配\n"); return ; } int i,j,x = 0,k = 1,numbers = 0,s; int matrix1[TSM1.rows+1][TSM1.cols+1]; int matrix2[TSM2.rows+1][TSM2.cols+1]; TSMatrix TSM3; TSM3.rows = TSM1.rows; TSM3.cols = TSM2.cols; TSM3.numbers = 0; ChangeToMatrix(TSM1,matrix1); //將三元組恢復成矩陣 ChangeToMatrix(TSM2,matrix2); for(i = 1;i <= TSM1.rows;i++) { //第一個矩陣的行迴圈 for(s = 1;s <= TSM2.cols;s++) { //第二個矩陣的列迴圈 for(j = 1;j <= TSM1.cols;j++) { //分別相乘 x += matrix1[i][j] * matrix2[j][s]; } if(x != 0) { //若不為0就儲存到三元組中 TSM3.numbers++; TSM3.data[k].row = i; TSM3.data[k].col = s; TSM3.data[k].value = x; k++; } x = 0; //注意要將x置0 } } printf("---相乘之後的矩陣---"); ShowMatrix(TSM3); } void AddMatrix(TSMatrix *T1,TSMatrix *T2) { int i; if(T1->cols != T2->cols || T1->rows != T2->rows) { printf("矩陣格式不匹配\n"); return ; } for(i = 1;i <= T1->rows+T2->rows;i++) { if(T1->data[i].row == T2->data[i].row && T1->data[i].col == T2->data[i].col) { //行列匹配就相加 //T1->data[i].value = T1->data[i].value + T2->data[i].value; T1->data[i].value = T1->data[i].value - T2->data[i].value; } else { T1->data[i+T1->rows].row = T2->data[i].row; //如果不匹配就放到第一個三元組後面 T1->data[i+T1->rows].col = T2->data[i].col; T1->data[i+T1->rows].value = T2->data[i].value; T1->numbers = i+T1->rows; } } } void Transpose_once(TSMatrix *T) { int i,j,k; TSMatrix S; int num[MAXSIZE]; int position[MAXSIZE]; S.cols = T->cols; S.rows = T->rows; S.numbers = T->numbers; for(i = 1; i <= T->cols;i++) { //num陣列實際上相當於桶排的原理,反映了從小到大col為不同數值的個數 num[i] = 0; } for(i = 1; i <= T->numbers;i++) { num[T->data[i].col]++; } position[1] = 1; for(i = 2;i <= T->cols;i++) { position[i] = position[i-1] + num[i-1]; //因為col有重複的,這樣就可以確定目前我下一個col值的位置應該跨越 //上一個col值的總個數 } for(j = 1;j <= T->numbers;j++) { k = T->data[j].col; //依次處理每一個col值 i = position[k]; //根據position陣列確定此col值定位之後的位置, S.data[i].row = T->data[j].col; //改變相應的值 S.data[i].col = T->data[j].row; S.data[i].value = T->data[j].value; position[k]++; //若有重複col值,下一次應該得到的position值是上一次加一。 } } void Transpose_coladd(TSMatrix *T) { TSMatrix S; int i,j = 1,k,temp; S.cols = T->rows; S.rows = T->cols; S.numbers = T->numbers; for(k = 1;k <= T->cols;k++) { for(i = 1;i <= T->numbers;i++) { //從小到大每次找出一個col值的所有個數依次存S中。 if(T->data[i].col == k) { S.data[j].row = T->data[i].col; S.data[j].col = T->data[i].row; S.data[j].value = T->data[i].value; j++; } if(j > T->numbers) { break; } } } for(i = 1;i <= S.numbers;i++) { printf("%d %d %d\n",S.data[i].row,S.data[i].col,S.data[i].value); } ShowMatrix(S); } void Transpose_rowsadd(TSMatrix *T) //行增加,直接交換即可,但是之後操作不方便 { int i,temp; temp = T->rows; T->rows = T->cols; T->cols = temp; for(i = 1;i < T->numbers+1;i++) { temp = T->data[i].row; T->data[i].row = T->data[i].col; T->data[i].col = temp; } for(i = 1;i < T->numbers+1;i++) { printf("%d %d %d\n",T->data[i].row,T->data[i].col,T->data[i].value); } } void ShowMatrix(TSMatrix TSM) { int i,j; int matrix[TSM.rows+1][TSM.cols+1]; for(i = 1;i <= TSM.rows;i++) { for(j = 1;j <= TSM.cols;j++) { matrix[i][j] = 0; } } for(i = 1;i <= TSM.numbers;i++) { matrix[TSM.data[i].row][TSM.data[i].col] = TSM.data[i].value; } printf("\n"); for(i = 1;i <= TSM.rows;i++) { for(j = 1;j <= TSM.cols;j++) { printf("%-4d",matrix[i][j]); } printf("\n"); } } void InitTSM(TSMatrix *T) { int i; printf("請輸入總元素個數:"); scanf("%d",&T->numbers); printf("請輸入總的行數:"); scanf("%d",&T->rows); printf("請輸入總列數:"); scanf("%d",&T->cols); for(i = 1;i <= T->numbers;i++) { printf("請依次輸入row,col,value:"); scanf("%d %d %d",&T->data[i].row,&T->data[i].col,&T->data[i].value); } } int main(int argc,char *argv[]) { int i,j; TSMatrix TSM,TSM1,TSM2; InitTSM(&TSM); //初始化矩陣 ShowMatrix(TSM); //通過三元組顯示矩陣 Transpose_rowsadd(&TSM); //行遞增轉置 Transpose_coladd(&TSM); //列遞增轉置演算法 Transpose_once(&TSM); //一次定位快速轉置 InitTSM(&TSM1); ShowMatrix(TSM1); InitTSM(&TSM2); ShowMatrix(TSM2); AddMatrix(&TSM1,&TSM2); //矩陣的加法和減法 MultiMatrix(TSM1,TSM2); //矩陣的乘法 return 0; }