采用压缩矩阵存储结构求d=a*b-c
时间: 2023-04-23 22:03:22 浏览: 120
压缩矩阵存储结构是一种将矩阵中的零元素省略掉,只存储非零元素及其位置的方法。对于矩阵乘法运算,可以采用压缩矩阵存储结构来提高计算效率。
假设矩阵a、b、c均为n阶矩阵,采用压缩矩阵存储结构后,可以将矩阵a、b、c分别表示为三元组(a1, a2, a3)、(b1, b2, b3)、(c1, c2, c3),其中a1、b1、c1分别表示非零元素的值,a2、b2、c2分别表示非零元素所在的行号,a3、b3、c3分别表示非零元素所在的列号。
则矩阵乘法d=a*b-c的计算过程如下:
1. 对于矩阵b,将其转置得到b',即将b中的行列互换,得到三元组(b1, b3, b2)。
2. 对于矩阵a和b',按照矩阵乘法的定义,分别遍历它们的非零元素,找到对应的行和列,计算乘积并将结果累加到d的对应位置上。
具体地,对于a的第i行和b'的第j行,如果它们存在相同的列k,即a中第i行的第k个元素和b'中第j行的第k个元素都非零,则将它们相乘并累加到d的第i行第j列上。
3. 最后,再将矩阵c中的每个元素减去对应位置上d的元素,即可得到最终结果。
需要注意的是,在压缩矩阵存储结构中,由于省略了零元素,因此需要在计算过程中判断某个元素是否为零,以避免出现错误的计算结果。
相关问题
C语言数据结构稀疏矩阵的压缩存储及其(1) 稀疏矩阵的压缩存储:采用三元组表示,压缩存储稀疏矩阵 (2) 求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。 (3) 求出A的转置矩阵D,输出D。 (4) 求两
个具有相同行列数的稀疏矩阵A和B的相乘矩阵C,并输出C。
对于问题1,稀疏矩阵的压缩存储采用三元组表示,即对于一个 m 行 n 列的稀疏矩阵,只需要记录下其中非零元素的行、列、值即可。这里我们可以定义一个结构体来表示三元组:
```c
typedef struct {
int row; // 非零元素所在行
int col; // 非零元素所在列
int val; // 非零元素的值
} Triple;
```
对于一个稀疏矩阵,我们可以用一个 Triple 类型的数组来存储其中的所有非零元素。同时,我们还需要记录下稀疏矩阵的行数、列数和非零元素的个数,可以定义一个 SparseMatrix 类型来表示:
```c
typedef struct {
Triple data[MAXSIZE]; // 三元组数组
int rows, cols, nums; // 行数、列数、非零元素个数
} SparseMatrix;
```
对于问题2,我们需要先判断两个稀疏矩阵的行列数是否相同,若不同则无法相加。然后可以定义一个函数来实现稀疏矩阵的相加,具体实现可参考下面的代码:
```c
void addSparseMatrix(SparseMatrix A, SparseMatrix B, SparseMatrix *C) {
if (A.rows != B.rows || A.cols != B.cols) {
printf("Error: rows and cols of A and B do not match!\n");
return;
}
int i = 0, j = 0, k = 0;
while (i < A.nums && j < B.nums) {
if (A.data[i].row < B.data[j].row || (A.data[i].row == B.data[j].row && A.data[i].col < B.data[j].col)) {
C->data[k++] = A.data[i++];
} else if (A.data[i].row > B.data[j].row || (A.data[i].row == B.data[j].row && A.data[i].col > B.data[j].col)) {
C->data[k++] = B.data[j++];
} else { // A.data[i].row == B.data[j].row && A.data[i].col == B.data[j].col
int sum = A.data[i].val + B.data[j].val;
if (sum != 0) {
C->data[k].row = A.data[i].row;
C->data[k].col = A.data[i].col;
C->data[k].val = sum;
k++;
}
i++;
j++;
}
}
while (i < A.nums) C->data[k++] = A.data[i++];
while (j < B.nums) C->data[k++] = B.data[j++];
C->rows = A.rows;
C->cols = A.cols;
C->nums = k;
}
```
对于问题3,稀疏矩阵的转置可以简单地理解为将原矩阵中的行列互换。因此,我们只需要将原矩阵中每个非零元素的行列交换即可。具体实现可参考下面的代码:
```c
void transposeSparseMatrix(SparseMatrix A, SparseMatrix *D) {
D->rows = A.cols;
D->cols = A.rows;
D->nums = A.nums;
if (D->nums == 0) return;
int k = 0;
for (int col = 1; col <= A.cols; col++) {
for (int i = 0; i < A.nums; i++) {
if (A.data[i].col == col) {
D->data[k].row = A.data[i].col;
D->data[k].col = A.data[i].row;
D->data[k].val = A.data[i].val;
k++;
}
}
}
}
```
对于问题4,稀疏矩阵的相乘可以参考矩阵乘法的思路,具体实现可参考下面的代码:
```c
void multiplySparseMatrix(SparseMatrix A, SparseMatrix B, SparseMatrix *C) {
if (A.cols != B.rows) {
printf("Error: cols of A and rows of B do not match!\n");
return;
}
SparseMatrix BT;
transposeSparseMatrix(B, &BT); // 先将 B 转置,方便后面的计算
int *sums = (int*) calloc(BT.rows + 1, sizeof(int)); // 记录每行非零元素的个数
for (int i = 0; i < BT.nums; i++) {
sums[BT.data[i].row]++;
}
int *start = (int*) calloc(BT.rows + 1, sizeof(int)); // 记录每行第一个非零元素的位置
for (int i = 1; i <= BT.rows; i++) {
start[i] = start[i - 1] + sums[i - 1];
}
for (int i = 0; i < A.nums; i++) {
int row = A.data[i].row;
for (int j = start[row - 1]; j < start[row]; j++) {
if (A.data[i].col == BT.data[j].row) {
int sum = A.data[i].val * BT.data[j].val;
int col = BT.data[j].col;
C->data[C->nums].row = row;
C->data[C->nums].col = col;
C->data[C->nums].val += sum;
C->nums++;
}
}
}
C->rows = A.rows;
C->cols = B.cols;
free(sums);
free(start);
}
```
以上就是关于 C 语言数据结构稀疏矩阵的压缩存储及其相关操作的实现。
一、问题描述 A 和 B 为两个 N 阶对称矩阵,求两个对称矩阵之和与乘积 、基本要求 (1)输人:只输人对称矩阵下三角元素,存储在一维数组中 (2)输出:以阵列方式输出 (3)实现两个对称矩阵的和 (4)实现两个对称矩阵的乘积 、设计提示 1.数据结构设计 N 阶对称矩阵形式上是个二维数组,压缩存储时只存储其对角线及其上或其下的元素到大小为 2* N-1的一维数组。按题目要求,存储下三角元素。 2.功能设计 完成该实验至少涉及以下4个功能 (1) 创建矩阵 (2)输出矩阵(3)求对称矩阵A和B的和。 (4)求对称矩阵A和B的乘积。
以下是一个简单的 C++ 实现,实现了上述要求:
```c++
#include <iostream>
using namespace std;
const int MAXN = 100;
int A[MAXN*(MAXN+1)/2], B[MAXN*(MAXN+1)/2], C[MAXN*(MAXN+1)/2], D[MAXN*(MAXN+1)/2];
// 创建对称矩阵
void createMatrix(int mat[], int n) {
int idx = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cin >> mat[idx++];
}
}
}
// 输出对称矩阵
void printMatrix(int mat[], int n) {
int idx = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << mat[idx++] << " ";
}
cout << endl;
}
}
// 计算两个对称矩阵的和
void addMatrix(int A[], int B[], int C[], int n) {
int idx = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
C[idx] = A[idx] + B[idx];
idx++;
}
}
}
// 计算两个对称矩阵的乘积
void multiplyMatrix(int A[], int B[], int D[], int n) {
int idx = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
int sum = 0;
for (int k = 1; k <= i; k++) {
if (k >= j) {
sum += A[idx-k+j-1] * B[(k-1)*k/2+i-1];
} else {
sum += A[idx+j-k-1] * B[(j-1)*j/2+k-1];
}
}
D[idx] = sum;
idx++;
}
}
}
int main() {
int n;
cout << "请输入矩阵阶数:";
cin >> n;
cout << "请输入对称矩阵 A:";
createMatrix(A, n);
cout << "请输入对称矩阵 B:";
createMatrix(B, n);
cout << "对称矩阵 A:" << endl;
printMatrix(A, n);
cout << "对称矩阵 B:" << endl;
printMatrix(B, n);
addMatrix(A, B, C, n);
cout << "对称矩阵 A+B:" << endl;
printMatrix(C, n);
multiplyMatrix(A, B, D, n);
cout << "对称矩阵 A*B:" << endl;
printMatrix(D, n);
return 0;
}
```
该程序使用一维数组存储对称矩阵,根据输入的下三角元素计算出每个元素在数组中的下标。在计算两个对称矩阵的乘积时,使用了一个小技巧:先将下标转换成对应的行和列,然后按照矩阵乘法的定义计算。
阅读全文