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