#include<iostream>
using namespace std;
template<class T>
struct matrixterms //每个非零元素
{
T element;
int mrow; //坐标
int mcol;
};
template<class T>
class spareMatrix
{
public:
spareMatrix(); //构造
~spareMatrix(){}; //析构 //为什么定义了析构函数后会出现提前结束的情况
void replace(); //重置
void multiply(spareMatrix<T> &Q); //乘法
void add(spareMatrix<T>); //加法
void output(); //输出
int getrow(){return row;} //求行数
int getcol(){return col;} //求列数
matrixterms<T> * gets(){return a;} //求一维数组
int anum; //稀疏矩阵的非0元素的个数
private:
matrixterms<T> *a;
int row,col; //矩阵行数,列数
};
//构造
template<class T>
spareMatrix<T>::spareMatrix()
{
a = NULL;
row = 0;
col = 0;
anum = 0;
}
//重置矩阵
template<class T>
void spareMatrix<T>::replace()
{
int n,m,k=0;
cin>>n>>m;
row = n;
col = m;
a = new matrixterms<T> [m*n];
// cout<<n<<" "<<m;
int num;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>num;
if(num!=0)
{
a[k].element=num;
a[k].mrow = i;
a[k].mcol = j;
k++;
}
}
} anum = k;
// cout<<"anum"<<anum<<endl;
//for(int i=0;i<anum;i++)
//{
// cout<<a[i].mrow<<","<<a[i].mcol<<" "<<a[i].element<<endl;
//}
}
//输出
template<class T>
void spareMatrix<T>::output()
{
int k= 0;
cout<<row<<" "<<col<<endl;
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
if(a[k].mrow==i&&a[k].mcol==j)
{ cout<<a[k].element<<" ";
k++;}
else
cout<<0<<" ";
}
cout<<endl;
}
}
//矩阵加法
template<class T>
void spareMatrix<T>::add(spareMatrix<T> Q)
{
int qrow=Q.getrow();
int qcol=Q.getcol();
if(qrow!=row||qcol!=col) //判断是否运算合法
{
a = Q.gets();
row = Q.getrow();
col = Q.getcol();
anum = Q.anum;
cout<<-1<<endl;
return;
}
else{
T *a1 = new T [row*col];
T *a2 = new T [row*col];
T *a3 = new T [row*col];
int k=0;
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(a[k].mrow==i&&a[k].mcol==j)
{
a1[i*col+j]=a[k].element;
k++;
}
else
a1[i*col+j]=0;
}k=0;
// for(int i=0;i<row;i++)
// for(int j=0;j<col;j++)
// {
// cout<<a1[i*col+j]<<endl;
// }
matrixterms<T> *c = Q.gets();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(c[k].mrow==i&&c[k].mcol==j)
{
a2[i*col+j]=c[k].element;
k++;
}
else
a2[i*col+j]=0;
}
// for(int i=0;i<row;i++)
// for(int j=0;j<col;j++)
// {
// cout<<a2[i*col+j]<<endl;
// }
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
a3[i*col+j]= a1[i*col+j]+a2[i*col+j];
}
// for(int i=0;i<row;i++)
// for(int j=0;j<col;j++)
// {
// cout<<a3[i*col+j]<<" ";
// }
k=0;
//将值赋给p
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(a3[i*col+j]!=0)
{a[k].element=a3[i*col+j];
a[k].mrow=i;
a[k].mcol=j;
k++;
}
}
anum = k;
delete c;
delete []a1;
delete []a2;
delete []a3;
// a = d;
// for(int i=0;i<row;i++)
// {
// for(int j=0;j<col;j++)
// {
// if(d[k].mrow==i&&d[k].mcol==j)
// { cout<<d[k].element<<" ";
// k++;}
// else
// cout<<0<<" ";
// }
// cout<<endl;
}
}
struct remenber
{
int k; //该行是否有非0元素,有1无0
int nn; //该元素在a中的位置
};
//乘法
template <class T>
void spareMatrix<T>::multiply(spareMatrix<T> &Q)
{
if( col!=Q.getrow() ) //判断合法
{
a = Q.gets();
row = Q.getrow();
col = Q.getcol();
anum = Q.anum;
cout<<-1<<endl;
return;}
else{
//1.先把被乘矩阵的 每行第一个非0元素的位置储存起来
//2.把每行非0元素的个数记录
//创建动态的不规则2维数组
matrixterms<T> *q=Q.gets();
matrixterms<T> c[row*col];
//记录每行的非0元素个数
int rowEnum[row];
for(int i=0;i<row;i++)
rowEnum[i]=0; //初始化
for(int i=0;i<anum;i++)
{
for(int j=0;j<row;j++)
if(a[i].mrow==j)
{
rowEnum[j]++;
}
}
// for(int i=0;i<row;i++)
// cout<<rowEnum[i]<<endl;
//记录每行第1个非0元素在a的位置
remenber re[row];
for(int i=0,j=0;j<row;i+=rowEnum[j],j++)
{ //cout<<j<<"***"<<endl;
// cout<<"i="<<i<<endl;
if(rowEnum[j]!=0)
{
re[j].k=1;
re[j].nn=i;
// cout<<i<<" ";
}
else
{re[j].k=0;
re[j].nn=-1;
if(i==anum)
break;
// cout<<"************"<<endl;
}
}
//for(int i=0;i<row;i++)
// cout<<"非0第1个 在a的位置为 "<<re[i].nn<<" "<<re[i].k<<endl;
//创建结果一维矩阵
//相乘
int sum1=0,sum2=0;
int jishu=0,m=0;
for(int i=0, N=rowEnum[0];i<row;i++,N+=rowEnum[i]) //A的行
{ // cout<<"P的行 "<<i<<endl;
if(re[i].k==0) //若i行没有非0元素,则结果一整行都是0
{
if(i==row-1)
break;
else
continue;
}
if(re[i].k!=0) {
for(int l=0;l<Q.getcol();l++){ //Q的列
// cout<<"Q的列 "<<l<<endl;
for(int j=re[i].nn;j<N;j++) //N是i行第一个非0元素在a中的位置,这个循环是选择i行的元素 ,j是a中的位置
{ // cout<<"P选的第一"<<j<<" ";
for(int g=0;g<Q.anum;g++){ //遍历q,寻找相乘
if(q[g].mcol==l&&a[j].mcol==q[g].mrow)
{ // cout<<"P的"<<i<<"行第"<<a[j].mcol<<"个乘Q的"<<l<<"列第"<<q[g].mrow<<"个"<<endl;
sum1 += a[j].element*q[g].element;
// cout<<"sum1="<<sum1<<" ";
jishu++;
sum2 = sum2+sum1; // cout<<"sum2="<<sum2<<endl;
}
if(g==Q.anum-1&&jishu==0)
{
sum1=0; //本次相乘等于0
}
jishu=0;
sum1=0;
}
}
if(sum2!=0)
{
c[m].element=sum2;
c[m].mrow=i;
c[m].mcol=l;
// cout<<"第"<<c[m].mrow<<"行第"<<c[m].mcol<<"列的值是"<<c[m].element<<endl;
m++;
}
sum2=0; //一个列确定一个元素,算完一个元素就归0
}
}}
//将结果赋给P
for(int i=0;i<m;i++)
{
a[i].element=c[i].element;
a[i].mcol=c[i].mcol;
a[i].mrow=c[i].mrow;
//cout<<"第"<<a[i].mrow<<"行第"<<a[i].mcol<<"列的值是"<<a[i].element<<endl;
}
col = Q.getcol();
anum = m;
// delete c;
// delete q;
// delete rowEnum;
// delete re;
// return;
//for(int i=0;i<m;i++)
// cout<<a[i].element<<" "<<a[i].mrow<<","<<a[i].mcol<<endl;
}
}
int main()
{
spareMatrix<int> p;
int n; //操作次数
cin>>n;
int cho; //选择操作
for(int i=0;i<n;i++)
{
cin>>cho;
switch (cho){
case 1:{
p.replace();
break;
}
case 2:{
spareMatrix<int> g;
g.replace();
p.multiply(g);
break;
}
case 3:{
spareMatrix<int> h;
h.replace();
p.add(h);
break;
}
case 4:{
p.output();
break;
}
default:{
break;
}
}
}
}
稀疏矩阵
最新推荐文章于 2023-03-29 16:33:29 发布