稀疏矩阵

#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;
   } 
  }
  } 
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值