三元组表(顺序)表示下的稀疏矩阵的转置与相乘

#include<stdio.h>
#include<stdlib.h>
#define Compare(x,y)						(((x)<(y))?-1:((x)==(y)?0:1)
typedef struct term {
	int row, col, value;
}Term;
typedef struct striples {
	int rows; int cols; int nonzeros;
	Term elem[31];
}Triples;
Triples Trans(Triples a);
Triples Multiply(Triples firstMatrix, Triples secondMatrix);
//主函数包括稀疏矩阵的普通形态与三元组表形态的互相转换方法
void main() {
	Triples firstMatrix;
	Triples secondMatrixOrigin;
	Triples secondMatrixTrans;
	Triples multResult;
	int i, j;
	int a[3][2] = { {3,1},
		{0,1},
		{2,3}
	};
	int b[2][5] = { {2,0,1,1,0},
		{0,1,0,1,1}
	};
	int secondMatrixTransArray[5][2] = { 0 };
	int resultArray[3][5] = { 0 };
	firstMatrix.rows = 3;
	firstMatrix.cols = 2;
	firstMatrix.nonzeros = 0;
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 2; j++) {
			printf("%5d ", a[i][j]);
		}
		printf("\n");
	}
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 2; j++) {
			if (a[i][j] != 0) {
				firstMatrix.elem[firstMatrix.nonzeros].row = i;
				firstMatrix.elem[firstMatrix.nonzeros].col = j;
				firstMatrix.elem[firstMatrix.nonzeros].value = a[i][j];
				firstMatrix.nonzeros++;
			}
		}
	}
	for (i = 0; i < firstMatrix.nonzeros; i++) {
		printf("%d     %d    %d \n", firstMatrix.elem[i].row, firstMatrix.elem[i].col, firstMatrix.elem[i].value);
	}
	printf("\n");
	secondMatrixOrigin.rows = 2;
	secondMatrixOrigin.cols = 5;
	secondMatrixOrigin.nonzeros = 0;
	for (i = 0; i < 2; i++) {
		for (j = 0; j < 5; j++) {
			printf("%5d ", b[i][j]);
		}
		printf("\n");
	}
	for (i = 0; i < 2; i++) {
		for (j = 0; j < 5; j++) {
			if (b[i][j] != 0) {
				secondMatrixOrigin.elem[secondMatrixOrigin.nonzeros].row = i;
				secondMatrixOrigin.elem[secondMatrixOrigin.nonzeros].col = j;
				secondMatrixOrigin.elem[secondMatrixOrigin.nonzeros].value = b[i][j];
				secondMatrixOrigin.nonzeros++;
			}
		}
	}
	for (i = 0; i < secondMatrixOrigin.nonzeros; i++) {
		printf("%d     %d    %d \n", secondMatrixOrigin.elem[i].row, secondMatrixOrigin.elem[i].col, secondMatrixOrigin.elem[i].value);
	}
	printf("\n");
	printf("\n");
	secondMatrixTrans = Trans(secondMatrixOrigin);
	for (i = 0; i < secondMatrixTrans.nonzeros; i++) {
		printf("%d     %d    %d \n", secondMatrixTrans.elem[i].row, secondMatrixTrans.elem[i].col, secondMatrixTrans.elem[i].value);
	}
	for (i = 0; i < secondMatrixTrans.nonzeros; i++) {
		secondMatrixTransArray[secondMatrixTrans.elem[i].row][secondMatrixTrans.elem[i].col] = secondMatrixTrans.elem[i].value;
	}
	for (i = 0; i < 5; i++) {
		for (j = 0; j < 2; j++) {
			printf("%5d ", secondMatrixTransArray[i][j]);

		}
		printf("\n");
	}

	multResult = Multiply(firstMatrix, secondMatrixTrans);
	for (i = 0; i < multResult.nonzeros; i++) {
		printf("%d     %d    %d \n", multResult.elem[i].row, multResult.elem[i].col, multResult.elem[i].value);
	}
	printf("\n");
	for (i = 0; i < multResult.nonzeros; i++) {
		resultArray[multResult.elem[i].row][multResult.elem[i].col] = multResult.elem[i].value;
	}

	for (i = 0; i < 3; i++) {
		for (j = 0; j < 5; j++) {
			printf("%5d ", resultArray[i][j]);
		}
		printf("\n");
	}
}
//三元组表顺序表示下的稀疏矩阵转置
Triples Trans(Triples a) {
	Triples b;
	int num[10], k[10], i, j, cols = a.cols, nonzeros = a.nonzeros;
	b.rows = a.cols;
	b.cols = a.rows;
	b.nonzeros = a.nonzeros;
	if (nonzeros > 0) {
		for (i = 0; i < cols; i++) {
			num[i] = 0;
		}
		for (i = 0; i < nonzeros; i++) {
			num[a.elem[i].col]++;
		}
		k[0] = 0;
		for (i = 1; i < cols; i++) {
			k[i] = k[i - 1] + num[i - 1];
		}
		for (i = 0; i < nonzeros; i++) {
			j = k[a.elem[i].col]++;
			b.elem[j].row = a.elem[i].col;
			b.elem[j].col = a.elem[i].row;
			b.elem[j].value = a.elem[i].value;
		}
	}
	return b;
}
//三元组表顺序表示下的稀疏矩阵相乘
Triples Multiply(Triples firstMatrix, Triples secondMatrix) {
	//Triples secondMatrixAfterTrans = Trans(secondMatrix);
	int  i, j, column, 
		totalFirstMatrix = firstMatrix.nonzeros, totalSecondMatrix = secondMatrix.nonzeros,
		totalResultMatrix = 0, rowsFirstMatrix = firstMatrix.rows, colsFirstMatrix = firstMatrix.cols, rowsSecondMatrix = secondMatrix.rows,
		rowBegin = 0, row = firstMatrix.elem[0].row, sum = 0;
	Triples resultMatrix;
	if (firstMatrix.cols!= secondMatrix.cols) {
		printf("无法对齐!");
		exit(1);
	}
	resultMatrix.rows = firstMatrix.rows;
	resultMatrix.cols = secondMatrix.rows;
	for (i = 0; i < firstMatrix.nonzeros;) {
		column = secondMatrix.elem[i].row;
		for (j = 0; j < secondMatrix.nonzeros+1;) {
			if (firstMatrix.elem[i].row!=row) {
				if (sum != 0) {
					resultMatrix.elem[totalResultMatrix].row = row;
					resultMatrix.elem[totalResultMatrix].col = column;
					resultMatrix.elem[totalResultMatrix++].value = sum;
				}
				sum = 0; i = rowBegin;
				for (; secondMatrix.elem[j].row == column; j++);
				column = secondMatrix.elem[j].row;
			}
			else {
				if (secondMatrix.elem[j].row != column) {
					if (sum != 0) {
						resultMatrix.elem[totalResultMatrix].row = row;
						resultMatrix.elem[totalResultMatrix].col = column;
						resultMatrix.elem[totalResultMatrix++].value = sum;
					}
					sum = 0;  i = rowBegin;
					column = secondMatrix.elem[j].row;
				}
				else {
					switch (Compare(firstMatrix.elem[i].col, secondMatrix.elem[j].col)))
					{
					case -1:
						i++; 
						break;
					case 0:
						sum += (firstMatrix.elem[i++].value) * (secondMatrix.elem[j++].value);
						break;
					case 1:
						j++;
						break;
					default:
						break;
					}
				}
			}
		}
		for (; firstMatrix.elem[i].row == row; i++);
		rowBegin = i;
		row = firstMatrix.elem[i].row;

	}
	resultMatrix.nonzeros = totalResultMatrix;
	return resultMatrix;
}

猜你喜欢

转载自blog.csdn.net/m0_47472749/article/details/121482275