稀疏矩阵相乘

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39984761/article/details/78533821

对于用三元组实现稀疏矩阵相乘的算法,首先构造一个结构体,结构图体中应该有五个量。其中第一个量是表示稀疏矩阵常用的三元组,定义如下:

typedef struct{
    int i, j;         //该非零元素行列下标
    ElemType e;
}Triple;
/*--------稀疏矩阵的三元组顺序表存储表示-------*/

下面是结构体的完整定义:

typedef struct {
    Triple data[MAXSIZE+1];   //三元组
    int num[MAXRC];           //一个数组记录矩阵每一行非零元个数
    int rpos [MAXRC+1];       //一个数组记录第一个非零元个数
    int mu, nu, tu;           //
    .

}RLSMatrix;

定义好结构体之后,我们要对结构体表示的矩阵实现矩阵相乘算法(注释已经写好了):

Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix &Q) {
    if (M.nu != N.mu)return ERROR;
    Q.mu = M.mu;
    Q.nu = N.nu;
    Q.tu = 0;
    if (M.tu*N.tu != 0) {                               //  说明Q是非零矩阵
            int ctemp[100];                             // 设置累加器ctemp数组
            int brow; 
            for (int col = 1; col < M.mu; ++col) {      //将表示M,N每行元素非零元个数的数组初始化
                M.num[col] = 0; N.num[col] = 0; }
            for (int t = 1; t <= M.tu; ++t) {
                ++M.num[M.data[t].i];

            }for (int t = 1; t <= N.tu; ++t) {
                ++N.num[N.data[t].i];

            }                                           //求出M,N每行元素非零元个数
            M.rpos[1] = 1;
            N.rpos[1] = 1;
            for (int col = 2; col <= M.mu; ++col) {
                M.rpos[col] = M.rpos[col - 1] + M.num[col - 1];
                N.rpos[col] = N.rpos[col - 1] + N.num[col - 1];
            }                                            //通过计算得出每行第一个非零元在三元组中的位置并将其放入rpos数组
        for (int arow = 1;arow<=M.mu;arow++) {

            for (int j = 1; j <= N.nu; j++) ctemp[j] = 0;//初始化累加器
            Q.rpos[arow] = Q.tu + 1;
            int tp;
            if (arow < M.mu)tp = M.rpos[arow + 1];
            else { tp = M.tu + 1; }
            for (int p = M.rpos[arow]; p < tp; ++p) {            
                brow = M.data[p].j;                         //找到每行第一个非零元的列下标,此下标在N中对应一个行号
                int t;
                if (brow < N.mu)t = N.rpos[brow + 1];
                else { t = N.tu + 1; }                      //如果对应行不超过N的行数,设置t为下一行首字母下标,否则,则设置t为最后一个非零元下标
                for (int q = N.rpos[brow]; q < t; ++q) {
                    int ccol = N.data[q].j;
                    ctemp[ccol]+= M.data[p].e*N.data[q].e;  //在不超过t的范围内做对应乘和累加操作

                }
            }
            for(int ccol = 1;ccol<=Q.nu;++ccol) {
                if (ctemp[ccol]) {
                    if (++Q.tu > MAXSIZE)return ERROR;      //将该行非零元放入Q的三元组
                    Q.data[Q.tu].i = arow;
                    Q.data[Q.tu].j = ccol;
                    Q.data[Q.tu].e=ctemp[ccol];
                }
            }
        }
    }
    return OK;
}

之后在主函数中初始化M和N,并进行计算

int main(){
    RLSMatrix *a, *b, c;
    a = (RLSMatrix*)malloc(sizeof(RLSMatrix));
    b = (RLSMatrix*)malloc(sizeof(RLSMatrix));
    cout<<"请输入A矩阵的行列式和非零元素的值"<<endl;
    cin>> a->mu >> a->nu >> a->tu;                                     
    for (int i = 1; i <=a->tu; i++)
        cin >> a->data[i].i >> a->data[i].j >> a->data[i].e;
    cout << "请输入B矩阵的行列式和非零元素的值" << endl;
    cin >> b->mu >> b->nu >> b->tu;
    for (int i = 1; i <= b->tu; i++)
        cin >> b->data[i].i >> b->data[i].j >> b->data[i].e;

    if (!MultSMatrix(*a, *b, c)) {
        cout << "矩阵无法相乘" <<endl;
    }
    else {
        cout<<"结果如下"<<endl;
    }
    cout <<c.mu<<"\t"<<c.nu<<"\t"<<c.tu;
    for (int i = 1; i <= c.tu; i++) {
        cout << "\n" << c.data[i].i << "\t" << c.data[i].j << "\t" << c.data[i].e;
    }
    free(a); free(b);
    a = NULL;
    b = NULL;
    system("pause");
}

这样就完成了稀疏矩阵相乘的操作,也可以自己根据需要修改主函数

猜你喜欢

转载自blog.csdn.net/qq_39984761/article/details/78533821
今日推荐