稀疏矩阵

mac2024-05-12  36

#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)