实现三元组类
【题目要求】
按照给定的内容定义一个TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息。
输入:第一行输入矩阵的行m,列n和非零元个数num 后续num行依次输入每个非零元的行,列和非零元的值 。
输出:首先显示三元组数组的内容,数字之间间隔一个空格。 然后以二维数组形式排列的稀疏矩阵效果,数字之间间隔一个空格。 输出稀疏矩阵的基本信息:行数,列数和非零元个数。
【测试样例】
【样例输入】
3 4 4
1 1 2
3 4 1
2 1 13
2 2 -1
【样例输出】
Print triple array.
row col item
1 1 2 2
1 13 2 2
-1 3 4 1
Print sparse matrix.
2 0 0 0
13 -1 0 0
0 0 0 1
line=3,column=4,nonzero number=4
【提示】
将输入的行、列、非零元素信息插入到三元组的思路提示:
- 如果是第一次输入,i=0时,则直接插入。
- 如果不是第一次输入,则应该考虑插入到什么位置,三元组数据的排序是优先考虑行,然后考虑列。
- 找到插入位置后,例如需要插入在j的地方,则需要考虑是否需要将已有三元组后续的元素后移,为j腾出空间,然后再插入。 需要考虑一些特殊的情况: 输入时行号列号不按顺序,输入重复的行号和列号,则重复输入的数据只记录后者。
【题解代码】
/*
用三元组存储稀疏矩阵,仅实现稀疏矩阵类并显示
*/
//用三元组存储稀疏矩阵(仅存储,不计算)
#include <iostream>
using namespace std;
#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型
typedef struct{
int row,col; //三元组的行号、列号;
int item; //三元组的值;
}Triple;
//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix{
private:
Triple data[MAX];//非零元三元组
int mu,nu,num; //矩阵的行数、列数和非零元个数
public:
TripleMatrix();
TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
~TripleMatrix();
Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
int getItem(int row,int col);//根据行号列号,获得矩阵元素值
void printMatrix();//按矩阵方式打印稀疏矩阵
void printTriple();//打印三元组数组
};
//填写代码实现三元组类中的成员函数
TripleMatrix::TripleMatrix()
{
mu=0;
nu=0;
num=0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
nu=n;
mu=m;
num=0;
}
TripleMatrix::~TripleMatrix()
{
//使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
if(row>mu||col>nu)//超范
return ERROR;
if(num==MAX)//即将超范
return ERROR;
if(item==0)//为0时不需要存储
return OK;
int index=0;
while(index<num)
{
if(row>data[index].row)//要找的行和列比三元组中已有的行列大
index++;
else if(row==data[index].row&&col>data[index].col)//要找的行号相等,列不相等,继续找列
index++;
else{ //找到了应该插入的位置
break;
}
}
if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
data[index].item=item;
else //需要插入新元素
{
for(int i=num;i>index;i--)//先从后往前把后面所有的元素向后以腾出新元素的位置
{
data[i].row=data[i-1].row; //可以简化成data[i]=data[i-1];
data[i].col=data[i-1].col;
data[i].item=data[i-1].item;
}
//再在index的位置存入新元素
data[index].row=row;
data[index].col=col;
data[index].item=item;
num++;
}
return OK;
}
int TripleMatrix::getItem(int row,int col)
{
if(row>mu||col>nu)
return 0;
for(int i=0;i<num;i++)//如果行和列匹配三元组,返回非零元
{
if(data[i].row==row&&data[i].col==col)
{
return data[i].item;
}
}
}
void TripleMatrix::printMatrix()
{
int tripleindex=0;
cout<<"Print sparse matrix.\n";
for(int i=1;i<=mu;i++)
{
for(int j=1;j<=nu;j++)
{
if(i==data[tripleindex].row&&j==data[tripleindex].col)
{ //如果找到了行列号匹配的三元组就输出非零元
cout<<data[tripleindex].item;
tripleindex++;
if(j<nu)
cout<<" ";
}
else
cout<<"0 ";
}
cout<<endl;
}
cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<num;
return ;
}
void TripleMatrix::printTriple()
{
cout<<"Print triple array."<<endl;
cout<<"row col item"<<endl;
for(int i=0;i<num;i++)
{
cout<<data[i].row<<" ";
cout<<data[i].col<<" ";
cout<<data[i].item<<endl;
}
}
//输入函数
void inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
int row,col,item;
for(int i=1;i<=num;i++)
{
cout<<"输入行列和非零元:\n";
cin>>row>>col>>item;
if(item!=0)
{
if(triple.setItem(row,col,item)==ERROR)
{
cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
break;
}
}
}
}
int main(){
int m,n,num;
cout << "请输入矩阵的行,列和非零元个数:";
cin >> m >> n >> num;
TripleMatrix triple(m,n);
inputMatrix(m,n,num,triple);
triple.printTriple();
triple.printMatrix();
return 0;
}
稀疏矩阵加法
【题目要求】
实现稀疏矩阵的加法,输入任意两个稀疏矩阵A和B,求出它们的和矩阵C。
实现步骤是:
(1) 创建三个稀疏矩阵。
(2)实现加法运算。
(3)输出稀疏矩阵相加的结果。
[输入说明]
第一行输入第一个矩阵的行n,列m,非零元素个数num(行列的序号从1开始) 后续num行依次输入行row,列col和非零元item 接着输入第二个矩阵的行n,列m,非零元素个数num 后续num行依次输入行row,列col和非零元item
[输出说明]
需要对输入的两个矩阵进行检查,仅有行列相同的矩阵才能相加。 如果矩阵可以相加,则在矩阵相加后,打印矩阵内容。并显示矩阵行列数和非零元个数。 如果矩阵不能相加,则提示错误:Matrices cannot be added.
【测试样例】
【输入数据1】
3 3 2
1 1 5
2 3 1
3 3 4
1 1 5
1 2 6
3 2 1
2 1 1
【输出数据1】
After add:
10 6 0
1 0 1
0 1 0
line=3,column=3,nonzero number=5
【输入数据2】
3 3 2
1 1 5
2 3 1
3 2 2
1 1 5
1 2 6
【输出数据2】
Matrices cannot be added.
【题解代码】
/*
用三元组存储稀疏矩阵,并完成加法(头歌使用的例子)
这个例子输入行号,列号,非零元,再存储
*/
#include <iostream>
using namespace std;
#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型
typedef struct{
int row,col; //三元组的行号、列号;
int item; //三元组的值;
}Triple;
//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix{
private:
Triple data[MAX];//非零元三元组
int mu,nu,num; //矩阵的行数、列数和非零元个数
public:
TripleMatrix();
TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
~TripleMatrix();
Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
int getItem(int row,int col);//根据行号列号,获得矩阵元素值
void printMatrix();//按矩阵方式打印稀疏矩阵
void printTriple();//打印三元组数组
void inputMatrix(int m,int n,int num,TripleMatrix& triple);
friend bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result);
};
TripleMatrix::TripleMatrix(){
//初始化矩阵的行数、列数和非零元个数
mu = 0;
nu = 0;
num = 0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
nu=n;
mu=m;
num=0;
}
//自己填写代码实现三元组类
TripleMatrix::~TripleMatrix()
{
//使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
if(row>mu||col>nu)//超范
return ERROR;
if(num==MAX)//即将超范
return ERROR;
if(item==0)//为0时不需要存储
return OK;
int index=0;
while(index<num)
{
if(row>data[index].row)//要找的行和列比三元组中已有的行列大
index++;
else if(row==data[index].row&&col!=data[index].col)//要找的行号相等,列不相等,继续找列
index++;
else{ //找到了应该插入的位置
break;
}
}
if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
data[index].item=item;
else //需要插入新元素
{
for(int i=num;i>index;i--)//先从后往前把后面所有的元素向后移腾出新元素的位置
{
data[i].row=data[i-1].row; //可以简化成data[i]=data[i-1];
data[i].col=data[i-1].col;
data[i].item=data[i-1].item;
}
//再在index的位置存入新元素
data[index].row=row;
data[index].col=col;
data[index].item=item;
num++;
}
return OK;
}
int TripleMatrix::getItem(int row,int col)
{
if(row>mu||col>nu)
return 0;
for(int i=0;i<num;i++)//如果行和列匹配三元组,返回非零元
{
if(data[i].row==row&&data[i].col==col)
{
return data[i].item;
}
}
return 0;
}
void TripleMatrix::printMatrix()
{
int tripleindex=0;
int count=0;//记录非零元个数
cout<<"Print sparse matrix.\n";
for(int i=1;i<=mu;i++)
{
for(int j=1;j<=nu;j++)
{
if(i==data[tripleindex].row&&j==data[tripleindex].col)
{ //如果找到了行列号匹配的三元组就输出非零元
cout<<data[tripleindex].item;
tripleindex++;
count++;
if(j<nu)
cout<<" ";
}
else{
cout<<"0";
if(j<nu)
cout<<" ";
}
}
cout<<endl;
}
cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<count;
return ;
}
void TripleMatrix::printTriple()
{
cout<<"Print triple array."<<endl;
cout<<"row col item"<<endl;
for(int i=0;i<num;i++)
{
cout<<data[i].row<<" ";
cout<<data[i].col<<" ";
cout<<data[i].item;
if(i<num-1)
cout<<endl;
}
}
//输入函数
void TripleMatrix::inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
int row,col,item;
for(int i=1;i<=num;i++)
{
//cout<<"输入行列和非零元:\n";
cin>>row>>col>>item;
if(item!=0)
{
if(triple.setItem(row,col,item)==ERROR)
{
cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
break;
}
}
}
}
/*
实现矩阵a与矩阵b的相加,结果放入矩阵result
如果矩阵可以相加,完成相加操作,结果放入result,并返回true
如果矩阵不能相加,返回false
*/
bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result){
//
if(a.mu!=b.mu||b.mu!=result.mu||a.nu!=b.nu||b.nu!=result.nu)
return false; //判断矩阵ab或result行列是否相等
else{
for(int i=1;i<=a.mu;i++) //遍历行
{
for(int j=1;j<=a.nu;j++) //遍历列
{
int item=a.getItem(i,j)+b.getItem(i,j);
if(item!=0)
result.setItem(i,j,item); //将非零元插入
}
}
return true;
}
}
/*加法的测试代码*/
int main(){
int m,n,num;
cout << "请输入第一个矩阵的行,列,非零元素个数:";
cin >> m >> n >> num;
cout << "第一个矩阵:"<< endl;
TripleMatrix tripleA(m,n);
tripleA.inputMatrix(m,n,num,tripleA);
// tripleA.printMatrix();
cout<<"\n请输入第二个矩阵的行,列,非零元个数:";
cin>>m>>n>>num;
cout<<"第二个矩阵:"<<endl;
TripleMatrix tripleB(m,n);
tripleB.inputMatrix(m,n,num,tripleB);
// tripleB.printMatrix();
TripleMatrix tripleResult(m,n);
if(matrixAdd(tripleA,tripleB,tripleResult))
{
cout<<"After add:"<<endl;
tripleResult.printMatrix();
}
else
cout<<"Matrices cannot be added.";
return 0;
}
稀疏矩阵乘法
【题目要求】
输入任意两个稀疏矩阵A和B,求出它们的乘积矩阵C。
实现步骤是:
(1) 创建三个稀疏矩阵。
(2) 实现乘法运算。
(3) 输出稀疏矩阵相乘的结果。
[输入说明]
第一行输入第一个矩阵的行n,列m,非零元素个数num
后续num行依次输入行row,列col和非零元item
接着输入第二个矩阵的行n,列m,非零元素个数num
后续num行依次输入行row,列col和非零元item
[输出说明]
需要对输入的两个矩阵进行检查,仅有符合矩阵相乘规则的矩阵才能相乘。
如果矩阵可以相乘,则在矩阵相乘后,打印矩阵内容。并显示矩阵行列数和非零元个数。
如果矩阵不能相乘,则提示错误:Matrices cannot be multiplied.
(这个题和上面的加法基本思路一样的,只需要改求和函数为求积函数即可)
【测试样例】
【输入数据】
3 3 2
1 1 5
2 3 1
3 2 2
1 1 2
3 1 4
【输出范例】
After Multiply:
10 0
4 0
0 0
line=3,column=2,nunzero number=2
【题解代码】
#include <iostream>
using namespace std;
#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型
typedef struct
{
int row,col; //三元组的行号、列号;
int item; //三元组的值;
} Triple;
//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix
{
private:
Triple data[MAX];//非零元三元组
int mu,nu,num; //矩阵的行数、列数和非零元个数
public:
TripleMatrix();
TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
~TripleMatrix();
Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
int getItem(int row,int col);//根据行号列号,获得矩阵元素值
void printMatrix();//按矩阵方式打印稀疏矩阵
void printTriple();//打印三元组数组
void inputMatrix(int m,int n,int num,TripleMatrix& triple);
friend bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result);
friend bool matrixMulty(TripleMatrix a,TripleMatrix b,TripleMatrix &result);
};
TripleMatrix::TripleMatrix()
{
//初始化矩阵的行数、列数和非零元个数
mu = 0;
nu = 0;
num = 0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
nu=n;
mu=m;
num=0;
}
//自己填写代码实现三元组类
TripleMatrix::~TripleMatrix()
{
//使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
if(row>mu||col>nu)//超范
return ERROR;
if(num==MAX)//即将超范
return ERROR;
if(item==0)//为0时不需要存储
return OK;
int index=0;
while(index<num)
{
if(row>data[index].row)//要找的行和列比三元组中已有的行列大
index++;
else if(row==data[index].row&&col!=data[index].col)//要找的行号相等,列不相等,继续找列
index++;
else //找到了应该插入的位置
{
break;
}
}
if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
data[index].item=item;
else //需要插入新元素
{
for(int i=num; i>index; i--) //先从后往前把后面所有的元素向后移腾出新元素的位置
{
data[i].row=data[i-1].row; //可以简化成data[i]=data[i-1];
data[i].col=data[i-1].col;
data[i].item=data[i-1].item;
}
//再在index的位置存入新元素
data[index].row=row;
data[index].col=col;
data[index].item=item;
num++;
}
return OK;
}
int TripleMatrix::getItem(int row,int col)
{
if(row>mu||col>nu)
return 0;
for(int i=0; i<num; i++) //如果行和列匹配三元组,返回非零元
{
if(data[i].row==row&&data[i].col==col)
{
return data[i].item;
}
}
return 0;
}
void TripleMatrix::printMatrix()
{
int tripleindex=0;
int count=0;//记录非零元个数
// cout<<"Print sparse matrix.\n";
for(int i=1; i<=mu; i++)
{
for(int j=1; j<=nu; j++)
{
if(i==data[tripleindex].row&&j==data[tripleindex].col)
{
//如果找到了行列号匹配的三元组就输出非零元
cout<<data[tripleindex].item;
tripleindex++;
count++;
if(j<nu)
cout<<" ";
}
else
{
cout<<"0";
if(j<nu)
cout<<" ";
}
}
cout<<endl;
}
cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<count;
return ;
}
void TripleMatrix::printTriple()
{
cout<<"Print triple array."<<endl;
cout<<"row col item"<<endl;
for(int i=0; i<num; i++)
{
cout<<data[i].row<<" ";
cout<<data[i].col<<" ";
cout<<data[i].item;
if(i<num-1)
cout<<endl;
}
}
//输入函数
void TripleMatrix::inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
int row,col,item;
for(int i=1; i<=num; i++)
{
//cout<<"输入行列和非零元:\n";
cin>>row>>col>>item;
if(item!=0)
{
if(triple.setItem(row,col,item)==ERROR)
{
cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
break;
}
}
}
}
bool matrixMulty(TripleMatrix a,TripleMatrix b,TripleMatrix& result)
{
//
int i,j,k;
if(a.nu!=b.mu) //判断是否满足可以相乘的条件,a列数等于b行数才能相乘
return false;
result.mu=a.mu; //初始化result的行列值
result.nu=b.nu;
//乘法计算
for(i=1; i<=a.mu; i++)
{
for(j=1; j<=b.nu; j++)
{
int sum=0;
for(k=1; k<=a.nu; k++)
{
sum+=a.getItem(i,k)*b.getItem(k,j);
}
if(sum!=0) //计算出来的值不为零才插入
result.setItem(i,j,sum);
}
}
return true;
}
int main()
{
int m,n,num;
cout << "请输入第一个矩阵的行,列,非零元素个数:";
cin >> m >> n >> num;
cout << "第一个矩阵:"<< endl;
TripleMatrix tripleA(m,n);
tripleA.inputMatrix(m,n,num,tripleA);
tripleA.printMatrix();
cout<<"\n输入第二个矩阵行,列,非零元个数:";
cin>>m>>n>>num;
cout<<"第二个矩阵"<<endl;
TripleMatrix tripleB(m,n);
tripleB.inputMatrix(m,n,num,tripleB);
tripleB.printMatrix();
TripleMatrix tripleResult;
if(matrixMulty(tripleA,tripleB,tripleResult))
{
cout<<"After Multiply:"<<endl;
tripleResult.printMatrix();
}
else
cout<<"Matrices cannot be multiplied.";
return 0;
}
。