数据结构 C 代码 5.2x: 压缩矩阵的转置与乘法 (2021学生版)

本贴为《数据结构》课程准备.
压缩矩阵是进行大数据处理的一种基本数据结构. 例如, 拥有 1 0 4 − 1 0 9 10^4-10^9 104109 个用户, 1 0 4 − 1 0 8 10^4-10^8 104108 个商品的推荐系统中, 假设用户平均购买的商品数为 1 0 2 10^2 102, 则压缩矩阵使用的空间仅为原始矩阵的 1 / 1 0 6 − 1 / 1 0 2 1/10^6-1/10^2 1/1061/102. 同时注意到, 在数据量大时存储原矩阵 ( 1 0 17 ≈ 1 0 5 10^{17} \approx 10^5 1017105 T) 根本就是不可能的事情.
本程序难度较大. 加法相比简单, 转置要考虑时间复杂度问题要难一点, 乘法就很难了, 我要找时间自己来写下.

1. 主要内容

  1. 压缩矩阵的三元组表示.
  2. 压缩矩阵的转置.
  3. 压缩矩阵的乘法.

2. 代码

2.1 潘家豪

#include<bits/stdc++.h>
using namespace std;
#define MAXSIZE 2000

typedef int elem;

typedef struct
{
    int i;
    int j;
    elem e;
} Triple;

typedef struct
{
    int mu,nu,tu;
    int SqPos[10];
    Triple data[MAXSIZE+1];
} RLSMatrix;

RLSMatrix M=
{
    3,3,7,{0,1,3,5},
    {
        {0,0,0},
        {1,1,1},
        {1,3,3},
        {2,2,2},
        {2,3,4},
        {3,1,3},
        {3,2,4},
        {3,3,3},
    }
};
/*
*	1 0 3
*	0 2 4
*	3 4 3
*/
RLSMatrix N=
{
    3,3,7,{0,1,3,6},
    {
        {0,0,0},
        {1,1,3},
        {1,2,2},
        {2,1,2},
        {2,2,3},
        {2,3,2},
        {3,2,2},
        {3,3,3},
    }
};
/*
*	3 2 0
*	2 3 2
*	0 2 3
*/

void TransSmatrix(RLSMatrix M);
void Print(RLSMatrix M);
void MultSmatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q);
void AddSmatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q);

int main()
{
    RLSMatrix Q,A;
    MultSmatrix(M,N,Q);
    printf("矩阵M:");
    Print(M);
    printf("矩阵N:");
    Print(N);
    printf("M和N相乘后的矩阵Q:");
    Print(Q);
    AddSmatrix(M,N,A);
    printf("M和N相加后的矩阵A:");
    Print(A);
    printf("矩阵M倒置后的矩阵:");
    TransSmatrix(M);
    return 0;
}


bool cmp(Triple M, Triple N)
{
    return M.i < N.i;
}

void TransSmatrix(RLSMatrix M)
{
    for (int i = 1; i <= M.tu; i++)
    {
        int temp = M.data[i].i;
        M.data[i].i = M.data[i].j;
        M.data[i].j = temp;
    }
    sort(M.data+1,M.data+M.tu+1,cmp);
    Print(M);
}

void Print(RLSMatrix M)
{
    int m=M.mu;
    int n=M.nu;
    int t=M.tu;
    printf("\n\n   i   j   e\n\n");
    for(int i=1; i<=t; i++)
    {
        printf("%4d%4d%4d\n",M.data[i].i,M.data[i].j,M.data[i].e);
    }
}

void MultSmatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)
{
    Q.mu=M.mu;
    Q.nu=N.nu;
    Q.tu=0;
    int M_row,N_row;
    for(M_row=1; M_row<=M.mu; M_row++)
    {
        int QElem[Q.nu+2]= {0};
        Q.SqPos[M_row]=Q.tu+1;

        int SqPos2_M;
        if(M_row<M.mu) SqPos2_M=M.SqPos[M_row+1];
        else SqPos2_M=M.tu+1;

        int SqPos_M;
        for(SqPos_M=M.SqPos[M_row]; SqPos_M<SqPos2_M; SqPos_M++)
        {
            N_row=M.data[SqPos_M].j;

            int SqPos2_N;

            if(N_row<N.mu) SqPos2_N=N.SqPos[N_row+1];
            else SqPos2_N=N.tu+1;

            int SqPos_N;
            for(SqPos_N=N.SqPos[N_row]; SqPos_N<SqPos2_N; SqPos_N++)
            {
                int col=N.data[SqPos_N].j;
                QElem[col]+=M.data[SqPos_M].e*N.data[SqPos_N].e;
            }
        }
        for(int col=1; col<=Q.nu; col++)
        {
            if(QElem[col]!=0)
            {
                ++(Q.tu);
                Q.data[Q.tu]= {M_row,col,QElem[col]};
            }
        }
    }
}

void AddSmatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)
{
    int i = 1, j = 1, k = 1;
    elem v;
    if(M.mu != N.mu||M.nu != N.nu) return;
    Q.mu = M.mu;
    Q.nu = N.nu;
    while(i <= M.tu && j <= N.tu)
    {
        if(M.data[i].i == N.data[j].i)
        {
            if(M.data[i].j < N.data[j].j)
            {
                Q.data[k].i = M.data[i].i;
                Q.data[k].j = M.data[i].j;
                Q.data[k].e = M.data[i].e;
                k++;
                i++;
            }
            else if(M.data[i].j > N.data[j].j)
            {
                Q.data[k].i = N.data[i].i;
                Q.data[k].j = N.data[i].j;
                Q.data[k].e = N.data[i].e;
                k++;
                j++;
            }
            else
            {
                v = M.data[i].e + N.data[j].e;
                if(v != 0)
                {
                    Q.data[k].i = M.data[i].i;
                    Q.data[k].j = M.data[i].j;
                    Q.data[k].e = v;
                    k++;
                }
                i++;
                j++;
            }
        }
        else if(M.data[i].i < N.data[j].i)
        {
            Q.data[k].i = M.data[i].i;
            Q.data[k].j = M.data[i].j;
            Q.data[k].e = M.data[i].e;
            k++;
            i++;
        }
        else
        {
            Q.data[k].i = N.data[i].i;
            Q.data[k].j = N.data[i].j;
            Q.data[k].e = N.data[i].e;
            k++;
            j++;
        }
        Q.tu = k-1;
    }
}

2.2 饶家一

#include<iostream>
#define MAXSIZE 100
using namespace std;

typedef struct Sparsematrix
{
    int row;//行
    int column;//列
    int data;
} Sparsematrix;

void print(Sparsematrix matrix[],int cnt);
void converse(int data[][MAXSIZE],int row,int column,int sparsematrix[][MAXSIZE]);
void add(int data[][MAXSIZE],int sparsematrix[][MAXSIZE],int row,int column);
void multiply(int data[][MAXSIZE],int sparsematrix[][MAXSIZE],int row,int column);
void compress(int data[][MAXSIZE],int row,int column);

int main()
{
    int row,column;
    cout<<"请输入矩阵的行大小:";
    cin>>row;
    cout<<"请输入矩阵的列大小:";
    cin>>column;

    int usermatrix[MAXSIZE][MAXSIZE];
    cout<<endl;

    for(int i=0; i<row; i++)
    {
        cout<<"请输入第"<<i+1<<"行的数据(以空格隔开):"<<endl;
        for(int j=0; j<column; j++)
        {
            cin>>usermatrix[i][j];
        }
    }
    cout<<endl;
    cout<<"压缩后矩阵如下:"<<endl;
    compress(usermatrix,row,column);
    cout<<endl;
    int conversematrix[MAXSIZE][MAXSIZE];
    cout<<"转置后:"<<endl;
    converse(usermatrix,row,column,conversematrix);
    cout<<endl;
    cout<<"与转置后矩阵相加后:"<<endl;
    add(usermatrix,conversematrix,row,column);
    cout<<endl;
    cout<<"与转置后矩阵相乘后:"<<endl;
    multiply(usermatrix,conversematrix,row,column);
    return 0;
}

void print(Sparsematrix matrix[],int cnt)
{
    cout<<"row"<<"      "<<"column"<<"      "<<"data"<<endl;
    for(int i = 0; i<cnt; i++)
    {
        cout<<matrix[i].row<<"           "<<matrix[i].column<<"          "<<matrix[i].data<<endl;
    }
}
void converse(int data[][MAXSIZE],int row,int column,int sparsematrix[][MAXSIZE])
{
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<column; j++)
        {
            sparsematrix[j][i]=data[i][j];
        }
    }
    for(int i = 0; i<column; i++)
    {
        cout<<endl;
        for(int j = 0; j<row; j++)
        {
            cout<<sparsematrix[i][j]<<' ';
        }
    }
}
void add(int data[][MAXSIZE],int sparsematrix[][MAXSIZE],int row,int column)
{
    int plusmatrix[MAXSIZE][MAXSIZE];
    for(int i = 0; i<row; i++)
    {
        for(int j = 0; j<column; j++)
        {
            plusmatrix[i][j] =  data[i][j]+sparsematrix[i][j];
        }
    }
    for(int i = 0; i<row; i++)
    {
        cout<<endl;
        for(int j = 0; j<column; j++)
        {
            cout<<plusmatrix[i][j]<<' ';
        }
    }
    cout<<endl;
    cout<<"压缩后:"<<endl;
    compress(plusmatrix,row,column);
}

void multiply(int data[][MAXSIZE],int sparsematrix[][MAXSIZE],int row,int column)
{
    int multiplymatrix[MAXSIZE][MAXSIZE];
    int sum;
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<row; j++)
        {
            for(int k=0; k<column; k++)
            {
                sum = data[i][k]*sparsematrix[k][j];
            }
            multiplymatrix[i][j]=sum;
            sum=0;
        }
    }
    for(int i = 0; i<row; i++)
    {
        cout<<endl;
        for(int j = 0; j<row; j++)
        {
            cout<<multiplymatrix[i][j]<<' ';
        }
    }
    cout<<endl;
    cout<<"压缩后:"<<endl;
    compress(multiplymatrix,row,row);
}

void compress(int data[][MAXSIZE],int row,int column)
{
    int cnt=0;
    Sparsematrix compressmatrix[MAXSIZE];
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<column; j++)
        {
            if(data[i][j]!=0)
            {
                compressmatrix[cnt].row=i+1;
                compressmatrix[cnt].column=j+1;
                compressmatrix[cnt].data=data[i][j];
                cnt++;
            }
        }
    }
    print(compressmatrix,cnt);
}

2.3 辜果

#include<stdio.h>
# define m 3
# define n 3
int a[m][n]=
{

    {1,0,1},
    {0,1,0},
    {1,0,1},
};

int b[m][n]=
{
    {0,0,1},
    {1,0,0},
    {1,0,0},
};

int c[m][n]=
{
    {0,0,0},
    {0,0,0},
    {0,0,0},
};

//定义结构体储存压缩后的矩阵
struct three
{
    int i,j;
    int value;
};

int numberb,numbera;
struct three stu1[9];
struct three stu2[9];
struct three stu3[9];
struct three stu4[9];
struct three stu5[9];

//压缩矩阵
int compress(int a[m][n],struct three *stu)
{
    int t=0;
    for(int r = 0; r<m; r++)
    {
        for(int c=0; c<n; c++)
        {
            if(a[r][c]!=0)
            {
                stu[t].i=r;
                stu[t].j=c;
                stu[t].value=a[r][c];
                t++;
            }
        }
    }
    return t;
}

//打印压缩后的矩阵
void display(struct three *stu)
{
    int x = 0;
    printf("压缩矩阵为:\n");
    for(x = 0; x<=9; x++)
    {
        if(stu[x].value!=0)
            printf("%d %d %d\n",stu[x].i,stu[x].j,stu[x].value);
    }
    printf("\n");
}

//转置矩阵
void zhuanzhi()
{
    int x,y;
    for(x = 0; x<m; x++)
    {
        for(y = 0; y<n; y++)
        {
            if(b[x][y]!=0)
            {
                c[y][x]=b[x][y];
            }
        }
    }
}

//矩阵相加
void xiangjia(struct three *stu1,struct three *stu2,struct three *stu4)
{
    int x = 0;
    int y = 0;
    int z = 0;
    while(x<=9 && z<=9)
    {
        if(stu1[x].i==stu2[z].i)
        {

            if(stu1[x].j<stu2[z].j)
            {
                stu4[y].i = stu1[x].i;
                stu4[y].j = stu1[x].j;
                stu4[y].value = stu1[x].value;
                y++;
                x++;
            }
            if(stu1[x].j == stu2[z].j)
            {
                stu4[y].i = stu2[z].i;
                stu4[y].j = stu2[z].j;
                stu4[y].value = stu1[x].value+stu2[z].value;
                y++;
                z++;
                x++;
            }
            if(stu1[x].j>stu2[z].j)
            {
                stu4[y].i = stu2[z].i;
                stu4[y].j = stu2[z].j;
                stu4[y].value = stu2[z].value;
                y++;
                z++;
            }
        }
        else if(stu1[x].i < stu2[z].i || z>=numberb )
        {
            stu4[y].i = stu1[x].i;
            stu4[y].j = stu1[x].j;
            stu4[y].value = stu1[x].value;
            y++;
            x++;
        }
        else
        {
            stu4[y].i = stu2[z].i;
            stu4[y].j = stu2[z].j;
            stu4[y].value = stu2[z].value;
            y++;
            z++;
        }
    }
}

//压缩后的矩阵相乘
void xiangcheng(struct three *stu1,struct three *stu3,struct three *stu5)
{
    int x = 0;
    int z = 0;
    int y = 0;
    for(; stu1[x].value!=0; x++)
    {
//		printf("i = %d j = %d value = %d\n",stu1[x].i,stu1[x].j,stu1[x].value);
        for(z=0; stu3[z].value!=0; z++)
        {

            if(stu1[x].j == stu3[z].j)
            {
//				printf("{i = %d j = %d value = %d}\n",stu3[z].i,stu3[z].j,stu3[z].value);
                int flag = 0;
                int t=0;
                int k;
                for( t = 0; stu5[t].value!=0; t++)
                {
                    k = 0;
                    if(stu5[t].i==stu1[x].i && stu5[t].j==stu3[z].i)
                    {
//						printf("t=%d\n",t);
                        flag=1;
//					    printf("stu5[t].i=%d stu1[x].j=%d stu5[t].j= %d stu3[z].i=%d\n",stu5[t].i,stu1[x].j,stu5[t].j,stu3[z].i);
                    }
                    k = t;
                }
//				printf("flag = %d\n",flag);
                if(flag==1)
                {
//					printf("k=%d",k);
//					printf("**********%d\n",stu5[k].value);
                    stu5[k-1].value += stu1[x].value*stu3[z].value;
//					printf("**********%d\n",stu5[k].value);
                }
                if(flag==0)
                {
                    stu5[y].i=stu1[x].i;
                    stu5[y].j=stu3[z].i;
                    stu5[y].value = stu1[x].value*stu3[z].value;
//					printf("[=====i = %d j = %d value = %d] %d\n",stu5[y].i,stu5[y].j,stu5[y].value,y);
                    y++;
                }

            }

        }
    }
}
int main()
{

    numbera = compress(a,stu1);
    printf("压缩矩阵1:\n");
    display(stu1);
    numberb = compress(b,stu2);
//	printf("%d",numberb);
    printf("压缩矩阵2:\n");
    display(stu2);
    zhuanzhi();
    numberb = compress(c,stu3);
    printf("转置后的压缩矩阵2:\n");
    display(stu3);
    printf("压缩矩阵相加后:\n");
    xiangjia(stu1,stu2,stu4);
    display(stu4);
    printf("压缩矩阵相乘:\n");
    xiangcheng(stu1,stu3,stu5);
    display(stu5);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值