三元組建立矩陣 一次定位快速轉置 矩陣的加法、減法、乘法
阿新 • • 發佈:2019-01-03
首先說說我們經常見到或者使用的矩陣:
(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;
}