数据结构与算法实验5——数组和矩阵

1.实验内容

创建稀疏矩阵类,采用行主顺序把稀疏矩阵非0元素映射到一维数组中,实现操作:两个稀疏矩阵相加、两个稀疏矩阵相乘、稀疏矩阵的转置、输出矩阵。

重置矩阵:操作1,即重置矩阵P的尺寸为n行m列,且随后按行优先顺序输入矩阵P的各个元素。

矩阵乘法:操作2,t行非零元素已按行优先顺序给出,矩阵中非零元素的表示为x y v,其中x表示行序号,y表示列序号,v表示非零元素值,行列序号从1开始。设输入的矩阵为Q,若P×Q运算合法,则将P×Q的结果矩阵赋给P,若不合法,则将Q赋给P,同时输出-1。

矩阵加法:操作3,t行非零元素已按行优先顺序给出,矩阵中非零元素的表示为x y v,其中x表示行序号,y表示列序号,v表示非零元素值,行列序号从1开始。设输入的矩阵为 Q,若P+Q运算合法,则将P+Q的结果矩阵赋给P,若不合法,则将Q赋给P,同时输出 -1。

输出操作:操作4,设当前矩阵P的尺寸为n行m列,第一行输出矩阵P的行数和列数,随后n行按行优先顺序输出矩阵P,每行m个数字,来表示当前的矩阵内容每行数字之间用空格分隔。

转置操作:操作5,设当前矩阵P的尺寸为n行m列,将其转置为m 行n列的矩阵,无需输出。

输入输出格式:

输入:

第一行一个w代表操作个数,接下来若干行是各个操作,其中保证第一个操作一定为重置矩阵。

输出:

当执行操作4时,输出矩阵P;当执行操作2或3时,若对应运算不合法,则输出-1。

2.测试结果

输入:

10

1

3 3

1 2 3

4 5 6

7 8 9

4

5

4

3

3 3

2

1 1 -1

2 1 7

4

2

3 3

3

1 1 1

2 2 1

3 3 1

4

3

2 2

4

1 1 -1

1 2 -2

2 1 -3

2 2 -4

4

输出:

3 3

1 2 3

4 5 6

7 8 9

3 3

1 4 7

2 5 8

3 6 9

3 3

0 4 7

9 5 8

3 6 9

3 3

0 4 7

9 5 8

3 6 9

-1

2 2

-1 -2

-3 -4

3.源代码

#include<iostream>

using namespace std;

template<class T>

struct matrixTerm //稀疏矩阵中元素的三要素

{

int row;

int col;

T value;

matrixTerm& operator=(matrixTerm& x){row=x.row;col=x.cow;value=x.value;return *this;}

};

template<class T>

class sparseMatrix

{

public:

sparseMatrix(int &m,int &n)//构造函数(m为行数,n为列数,terms为非零元素个数) 

{

rows=m;

cols=n;

terms=0;

termsArray=new matrixTerm<T>[m*n];

}

~sparseMatrix() //析构函数

{

delete []termsArray;

}

void changeSize(int m,int n) //改变矩阵大小

{

delete []termsArray;

rows=m;

cols=n;

terms=0;

termsArray=new matrixTerm<T>[m*n];

}

void sparseMatrixCopy(sparseMatrix<T> &A) //复制稀疏矩阵

{

delete []termsArray;

rows=A.rows;

cols=A.cols;

terms=A.terms;

termsArray=new matrixTerm<T>[terms];

for(int i=0;i<terms;i++)

{

termsArray[i].row=A.termsArray[i].row;

termsArray[i].col=A.termsArray[i].col;

termsArray[i].value=A.termsArray[i].value;

}

}

void inPut() //依次输入矩阵内的所有元素

{

T addValue;

int addTerms=0;

for(int i=0;i<rows*cols;i++)

{

cin>>addValue;

if(addValue!=0)

{

termsArray[terms].value=addValue;

termsArray[terms].col=i-(i/cols)*cols+1;

termsArray[terms].row=i/cols+1;

terms++;

}

}

}

void inPut2() //依次输入所有非0元素的三要素

{

int t;

cin>>t;

for(int i=0;i<t;i++)

{

int addRow,addCol;

T addValue;

cin>>addRow>>addCol>>addValue;

termsArray[i].value=addValue;

termsArray[i].col=addCol;

termsArray[i].row=addRow;

terms++;

}

}

void transpose() //矩阵转置

{

sparseMatrix<T> C(cols,rows);

int num[cols]; //数组num记录每一列(0至col-1)的非0元素个数

for(int i=0;i<cols;i++)

num[i]=0;

for(int i=0;i<terms;i++)

++num[termsArray[i].col-1];

int cpot[cols];

//数组cpot记录每一列(1至col)与之前所有列的非0元素个数之和

cpot[0]=0;

for(int i=1;i<cols;i++)

cpot[i]=cpot[i-1]+num[i-1];

for(int p=0;p<terms;p++) //将第p个非0元素存入C中

{

int col=termsArray[p].col-1;

int q=cpot[col];

C.termsArray[q].col=termsArray[p].row;

C.termsArray[q].row=termsArray[p].col;

C.termsArray[q].value=termsArray[p].value;

cpot[col]++;

}

C.terms=terms;

sparseMatrixCopy(C);       //把C复制给此矩阵

}

void outPut() //输出矩阵

{

int k=0;

cout<<rows<<" "<<cols<<endl;

for(int i=0;i<rows;i++)

{

for(int j=0;j<cols;j++)

{

if(k<terms && termsArray[k].row==i+1 && termsArray[k].col==j+1)

cout<<termsArray[k++].value<<" ";

else

cout<<0<<" ";

}

cout<<endl;

}

}

void multiply(sparseMatrix<T> &B) //矩阵乘法

{

if(cols!=B.rows) //矩阵乘法不合法

{

sparseMatrixCopy(B); //将实参矩阵赋给此矩阵

cout<<-1<<endl; //输出-1

}

else

{

sparseMatrix<T> C(rows,B.cols);

B.transpose(); //将B转置

int it=0,ib=0;

//it为此矩阵中已取的非0元素个数,ib为B中已去的非0元素个数

for(int i=0;i<rows;i++)

//求C中第i行(0至rows-1)第j列(0至B.cols-1)的元素

{

int flag=it;

ib=0;

for(int j=0;j<B.rows;j++)

{

int num=0; //num为这个元素的值

it=flag;

while(termsArray[it].row==i+1 && B.termsArray[ib].row==j+1)                    //此矩阵读取到第i行(1至rows),B读取到第j行(1至B.cols)

{

if(termsArray[it].col<B.termsArray[ib].col)

//此矩阵当前读取的非0元素的列小于B当前读取的非0元素的列,此矩阵读取坐标后移

it++;

else if(termsArray[it].col>B.termsArray[ib].col)

//此矩阵当前读取的非0元素的列大于B当前读取的非0元素的列,B读取坐标后移

ib++;

else

//此矩阵当前读取的非0元素的列等于B当前读取的非0元素的列,计算二者的积加入num,读取坐标均后移

{

num+=termsArray[it].value*B.termsArray[ib].value;

it++;

ib++;

}

}

while(termsArray[it].row==i+2 && B.termsArray[ib].row==j+1)           //此矩阵当前读取的非0元素已属于下一行,将B的读取坐标也移至下一行

ib++;

while(termsArray[it].row==i+1 && B.termsArray[ib].row==j+2)            //B当前读取的非0元素已属于下一行,将此矩阵的读取坐标也移至下一行

it++;

if(num!=0)                         //如果C中第i行第j列的元素不为0,将值记入C.termsArray

{

C.termsArray[C.terms].row=i+1;

C.termsArray[C.terms].col=j+1;

C.termsArray[C.terms].value=num;

C.terms++;

}

}

}

sparseMatrixCopy(C); //把C复制给此矩阵

}

}

void add(sparseMatrix<T> &B) //矩阵加法

{

if(rows!=B.rows || cols!=B.cols) //矩阵加法不合法

{

sparseMatrixCopy(B); //将实参矩阵赋给此矩阵

cout<<-1<<endl; //输出-1

}

else

{

sparseMatrix<T> C(rows,cols); //用稀疏矩阵C

int it=0,ib=0;

//it记录此矩阵中已取的非0元素个数,ib记录B中已取的非0元素个数

while(it!=terms && ib!=B.terms)   //此矩阵和B中的非0元素都未取完时

{

int tIndex=(termsArray[it]).row*cols+(termsArray[it]).col;

//此矩阵中下一个未取到的非0元素在矩阵中的一维位置

int bIndex=(B.termsArray[ib]).row*cols+(B.termsArray[ib]).col;

//B中下一个未取到的非0元素在矩阵中的一维位置

if(tIndex<bIndex)

//当此矩阵当前一维位置较小时,插入该矩阵中的当前元素

{

C.termsArray[C.terms].col=termsArray[it].col;

C.termsArray[C.terms].row=termsArray[it].row;

C.termsArray[C.terms].value=termsArray[it].value;

it++;

C.terms++;

}

else if(tIndex==bIndex)

//当此矩阵与B当前一维位置相同时,若和不为0,插入二者之和,若和为0,跳过这两个位置

{

if((termsArray[it]).value+(B.termsArray[ib]).value!=0)

{

C.termsArray[C.terms].col=(termsArray[it]).col;

C.termsArray[C.terms].row=(termsArray[it]).row;

C.termsArray[C.terms].value=(termsArray[it]).value+(B.termsArray[ib]).value;

C.terms++;

}

it++;

ib++;

}

else //当B当前一维位置较小时,插入B中的当前元素

{

C.termsArray[C.terms].col=B.termsArray[ib].col;

C.termsArray[C.terms].row=B.termsArray[ib].row;

C.termsArray[C.terms].value=B.termsArray[ib].value;

ib++;

C.terms++;

}

}

for(;it!=terms;it++) //继续取此矩阵中未取完的非0元素

{

C.termsArray[C.terms].col=termsArray[it].col;

C.termsArray[C.terms].row=termsArray[it].row;

C.termsArray[C.terms].value=termsArray[it].value;

C.terms++;

}

for(;ib!=B.terms;ib++) //继续取B中未取完的非0元素

{

C.termsArray[C.terms].col=B.termsArray[ib].col;

C.termsArray[C.terms].row=B.termsArray[ib].row;

C.termsArray[C.terms].value=B.termsArray[ib].value;

C.terms++;

}

sparseMatrixCopy(C); //把C复制给此矩阵

}

}

private:

int rows;

int cols;

int terms;

matrixTerm<T>* termsArray;

};

int main()

{

int w; //输入操作次数

cin>>w;

int op;

cin>>op; //输入操作类型

op=1; //强制第1次操作为重置矩阵

int m,n;

cin>>m>>n; //输入矩阵的行数和列数

sparseMatrix<int> M(m,n);

sparseMatrix<int> N(m,n);

M.inPut(); //输入矩阵的所有元素

for(int i=0;i<w-1;i++) //进行w-1次操作

{

cin>>op; //输入操作类型

switch(op)

{

case 1: //重置矩阵

cin>>m>>n; //输入重置后的行数和列数

N.changeSize(m,n); //将N重置为m行n列

N.inPut(); //输入N的所有元素

M.sparseMatrixCopy(N); //将N赋值给M

break;

case 2: //矩阵乘法

cin>>m>>n; //输入右矩阵的行数和列数

N.changeSize(m,n); //将N重置为m行n列

N.inPut2(); //输入N的非0元素

M.multiply(N); //将N右乘入M

break;

case 3: //矩阵加法

cin>>m>>n; //输入右矩阵的行数和列数

N.changeSize(m,n); //将N重置为m行n列

N.inPut2(); //输入N的非0元素

M.add(N); //将N加入M

break;

case 4: //输出矩阵

M.outPut();

break;

case 5: //转置矩阵

M.transpose();

break;

default:

break;

}

}

return 0;

}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值