行逻辑三元组稀疏矩阵加减乘的编程实现

匿名 (未验证) 提交于 2019-12-03 00:22:01

目的:
        编程实现稀疏矩阵的四则运算。
实现:
1. 稀疏矩阵的存储结构采用行逻辑表示的三元组
2.

#define MAXSIZE  12500 #define MAXRC 12500 typedef struct {     int i, j;     int e; }Triple; typedef struct {     Triple data[MAXSIZE + 1];     int rpos[MAXRC + 1];     int mu, nu, tu; }RLSMatrix;

        先通过创建mu nu tu的值再根据这些值采用循环输入得到data,之后再通过扫描确定rpos的值则可以完成创建。
        通过三元组的形式将非零元对应的行列以及数值存储下来,再由稀疏矩阵结构存下矩阵的行数列数以及非零元个数,即可囊括稀疏矩阵的所有信息。这样就可以以三元组的形式把矩阵非零元素存储下来,节省了存储量的同时便于矩阵运算。

  1. 矩阵的加法
           根据矩阵的相关知识,两个矩阵相加要求两个矩阵的行数,列数要相等。故需要设置判断是否满足矩阵相加的条件。若满足条件,则进行加法运算。根据矩阵加法法则,得到的新矩阵拥有与原来两矩阵相同的行数和列数,其元素数值则为两矩阵对应位置的元素值之和。

  2. 矩阵的减法
           和加法相同地根据三种情况采用三个循环处理对应的数据,只不过两个都有的情况结果要变为两者之差,N有M没有的情况要改为N元素的相反数,其余相同。则可以得到减法的算法。

  3. 矩阵的乘法
            根据矩阵乘法的理论,在满足M.nu==N.mu的情况下,新矩阵Q(i,j)的值即满足M(i,k)与N(k,j)的所有元素乘积之和。对于稀疏矩阵不需要对满足条件的每个元素都进行乘积,因为两者中若有一个为零则其乘积为零。所以只要在所有非零元中找到满足条件的配对进行相乘,在将乘积进行累加即可得到该位置的元素值。结合rpos可以高效地进行循环查找。
    程序代码:
    Matrix.h文件

#include<stdio.h> #define MAXSIZE  12500 #define MAXRC 12500 #define ERROR 0 #define OK 1 typedef struct {     int i, j;     int e; }Triple; typedef struct {     Triple data[MAXSIZE + 1];     int rpos[MAXRC + 1];     int mu, nu, tu; }RLSMatrix; void CreateMatrix(RLSMatrix *M); void Initrpos(RLSMatrix *M); void Printrpos(RLSMatrix M); int Add(RLSMatrix M, RLSMatrix N, RLSMatrix  *sum); int Minus(RLSMatrix M, RLSMatrix N, RLSMatrix *minus); int Multi(RLSMatrix M, RLSMatrix N, RLSMatrix *multi); void PrintMatrix(RLSMatrix M);

Matrix.c文件

#include<stdio.h> #include"Matrix.h" void CreateMatrix(RLSMatrix *M) {     printf("请输入矩阵的行数,列数,和非零元个数\n");     scanf("%d%d%d", &M->mu, &M->nu, &M->tu);     if (M->tu > (M->mu)*(M->nu)) { printf("该矩阵不存在!请重新输入!\n"); CreateMatrix(&M); }     int s;     for (s = 1; s <= M->tu; s++) {         printf("请输入第%d非零元所在的行,列,及其数值\n", s);         scanf("%d%d%d", &M->data[s].i, &M->data[s].j, &M->data[s].e);         if (M->data[s].i < 0) { printf("行数须为正数!\n"); s -= 1; continue; }         if(M->data[s].j < 0) { printf("列数须为正数!\n"); s -= 1; continue; }         if(M->data[s].e==0){ printf("非零元不能为零!\n"); s -= 1; continue; }     } } void Initrpos(RLSMatrix *M) {     int i, j, tag, s;     for (i = M->mu; i >= 1; i--) {         tag = 0;         for (j = 1; j <= M->nu; j++) {             for (s = 1; s <= M->tu; s++) {                 if (M->data[s].i == i&&M->data[s].j == j) {                     M->rpos[i] = s; tag = 1; break;                 }             }             if (tag == 1)break;         }         if (i == M->mu&&tag == 0)M->rpos[i] = M->tu + 1;         if (i != M->mu&&tag == 0)M->rpos[i] = M->rpos[i + 1];     } } void Printrpos(RLSMatrix M) {     int i;     printf("rpos\n");     for (i = 1; i <= M.mu; i++) {         printf("第%d行:%d\n", i, M.rpos[i]);     } }  int Add(RLSMatrix M, RLSMatrix N, RLSMatrix *sum) {     int m, n, c = 1;     if (M.mu != N.mu || M.nu != N.nu) { printf("无法相加!\n"); return ERROR; }     sum->mu = M.mu;     sum->nu = M.nu;     for (m = 1; m <= M.tu; m++) {         for (n = 1; n <= N.tu; n++) {             if (N.data[n].i == M.data[m].i&&N.data[n].j == M.data[m].j) {                 sum->data[c].i = N.data[n].i;                 sum->data[c].j = N.data[n].j;                 sum->data[c].e = M.data[m].e + N.data[n].e;                 c++;             }          }            }     for (m = 1; m <= M.tu; m++) {         for (n = 1; n <= N.tu; n++) {             if (N.data[n].i == M.data[m].i && N.data[n].j == M.data[m].j) {                  break;             }                    }         if (n-1 == N.tu) {             sum->data[c].i = M.data[m].i;             sum->data[c].j = M.data[m].j;             sum->data[c].e = M.data[m].e;             c++;         }     }      for (n = 1; n <= N.tu; n++) {         for (m = 1; m <= M.tu; m++) {             if (N.data[n].i == M.data[m].i && N.data[n].j == M.data[m].j) {                 break;             }         }         if (m-1 == M.tu) {             sum->data[c].i = N.data[n].i;             sum->data[c].j = N.data[n].j;             sum->data[c].e = N.data[n].e;             c++;         }     }     sum->tu = c - 1;     return OK; }  int Minus(RLSMatrix M, RLSMatrix N, RLSMatrix *minus) {     int m, n, c = 1;     if (M.mu != N.mu || M.nu != N.nu) { printf("无法相减!\n"); return ERROR; }     minus->mu = M.mu;     minus->nu = M.nu;     for (m = 1; m <= M.tu; m++) {         for (n = 1; n <= N.tu; n++) {             if (N.data[n].i == M.data[m].i&&N.data[n].j == M.data[m].j) {                 minus->data[c].i = N.data[n].i;                 minus->data[c].j = N.data[n].j;                 minus->data[c].e = M.data[m].e - N.data[n].e;                 c++;             }          }     }     for (m = 1; m <= M.tu; m++) {         for (n = 1; n <= N.tu; n++) {             if (N.data[n].i == M.data[m].i && N.data[n].j == M.data[m].j) {                  break;             }                    }         if (n-1 == N.tu) {             minus->data[c].i = M.data[m].i;             minus->data[c].j = M.data[m].j;             minus->data[c].e = M.data[m].e;             c++;         }     }     for (n = 1; n <= N.tu; n++) {         for (m = 1; m <= M.tu; m++) {             if (M.data[m].i == N.data[n].i && M.data[m].j == N.data[n].j) {                break;             }                    }         if (m-1 == M.tu) {             minus->data[c].i = N.data[n].i;             minus->data[c].j = N.data[n].j;             minus->data[c].e = -N.data[n].e;             c++;         }     }     minus->tu = c - 1;     return OK; } int Multi(RLSMatrix M, RLSMatrix N, RLSMatrix *Q) {     if (M.nu != N.mu)return ERROR;     Q->mu = M.mu; Q->nu=N.nu; Q->tu = 0;     int tp; int i;     int p, brow;     int q, ccol;     if (M.tu*N.tu != 0) {         int arow;         int ctemp[12500];         for (arow = 1; arow <= M.mu; ++arow) {             for (i = 1; i <= M.nu; i++) ctemp[i] = 0;             Q->rpos[arow] = Q->tu + 1;             if (arow < M.mu)tp = M.rpos[arow + 1];             else { tp = M.tu + 1; }             for (p = M.rpos[arow]; p<tp; ++p) {                 brow = M.data[p].j;                 int t;                 if (brow < M.mu)t = N.rpos[brow + 1];                 else { t = N.tu + 1; }                 for (q = N.rpos[brow]; q < t; ++q) {                     ccol = N.data
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!