第9周-任务4-二维数组类

简介: 【题目】建立一个二维数组类Douary,使该类中有以下数据成员、成员函数及友员函数,完成矩阵的输入、输出、加、减、相等判断等操作。 给出的代码部分如下: class Douary{public: Douary(int m, int n);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为0 ~Douary(); //析构函数:用于释放动态

【题目】建立一个二维数组类Douary,使该类中有以下数据成员、成员函数及友员函数,完成矩阵的输入、输出、加、减、相等判断等操作。

给出的代码部分如下:

class Douary
{public:
	Douary(int m, int n);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为0
	~Douary(); //析构函数:用于释放动态数组所占用的存储空间。
	friend istream &operator>>(istream &input, Douary &d);//重载运算符“>>”输入二维数组,d为Dousry类对象;
	friend ostream &operator<<(ostream &output, Douary &d);//重载运算符“<<”以m行n列形式输出,d为Douary类对象。
	friend Douary operator+(const Douary &d1,const Douary &d2);//两个矩阵相加,规则:对应位置上的元素相加
	friend Douary operator-(const Douary &d1,const Douary &d2);//两个矩阵相减,规则:对应位置上的元素相减
	bool operator==(const Douary &d);//判断两个矩阵是否相等,即对应位置上的所有元素是否相等
private:
	int * Array;      //Array 为动态数组指针。
	int row;          //row  为二维数组的行数。
	int col;          //col   为二维数组的列数。
}
int main()
{	Douary d1(2,3),d2(2,3)
	cout<<"输入d1:"<<endl;  	cin>>d1;
	cout<<"输入d2:"<<endl;  	cin>>d2;
	coutt<<"d1="<<endl;    	cout<<d1;
	coutt<<"d2="<<endl;    	cout<<d2;
	coutt<<"d1+d2="<<endl; 	cout<<(d1+d2);
	coutt<<"d1-d2="<<endl;	cout<<(d1-d2);
	cout<<"d1"<<((d1==d2)?"==":"!=")<<"d2"<<endl;
}

【说明】(1)在上面的成员函数中,少定义了一个复制构造函数。对一般的类而言,这个复制构造函数是默认的,但在此问题中却必须给出。详细讲解请参考:《 何时需要自定义复制构造函数?》(2)在初次给出的部分代码中,operate+、operate-和operate==的返回值都是引用型(&)的,这是不合适的。这也是一个值得搞清楚的问题,参考:《 函数返回值是否使用引用类型的问题:理解引用、返回值

【参考解答】

#include <iostream>
using namespace std;
class Douary
{
public:
	Douary(int m, int n);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为
	Douary(const Douary &d);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为
	~Douary(); //析构函数:用于释放动态数组所占用的存储空间
	friend istream &operator>>(istream &input, Douary &d);//重载运算符“>>”输入二维数组,其中d为Dousry类对象;
	friend ostream &operator<<(ostream &output, Douary &d);//重载运算符“<<”以m行n列矩阵的形式输出二维数组,其中d为Douary类对象。
	friend Douary operator+(const Douary &d1,const Douary &d2);//两个矩阵相加,规则:对应位置上的元素相加
	friend Douary operator-(const Douary &d1,const Douary &d2);//两个矩阵相减,规则:对应位置上的元素相减
	bool operator==(const Douary &d);//判断两个矩阵是否相等,即对应位置上的所有元素是否相等
private:
	int * Array;      //Array 为动态数组指针。
	int row;          //row  为二维数组的行数。
	int col;          //col   为二维数组的列数。
};

Douary::Douary(int m, int n) //构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为
{
	row=m;
	col=n;
	Array = new int[m*n]; //Array只能指向一维数组,将m*n个元素的一维数组当作m行n列的数组看待了
	for(int i=0; i<row; ++i)
		for(int j=0; j<col; ++j)
			Array[i*col+j]=0; //关键是给出各个元素地址的计算办法,此处还可以写作*(Array+i*col+j)=0; 
}

Douary::Douary(const Douary &d)
{
	row=d.row;
	col=d.col;
	Array = new int[row*col];
	for(int i=0; i<row; ++i)
		for(int j=0; j<col; ++j)
			Array[i*col+j]=d.Array[i*col+j]; //注意地址求法
}

Douary::~Douary() //析构函数:用于释放动态数组所占用的存储空间
{
	delete [] Array;
}

istream &operator>>(istream &input, Douary &d)//重载运算符“>>”输入二维数组,其中d为Dousry类对象
{
	for(int i=0; i<d.row; ++i)
		for(int j=0; j<d.col; ++j)
			cin>>d.Array[i*d.col+j];//注意地址求法
	return input;
}

ostream &operator<<(ostream &output, Douary &d)//重载运算符“<<”以m行n列矩阵的形式输出二维数组,其中d为Douary类对象
{
	for(int i=0; i<d.row; ++i)
	{
		for(int j=0; j<d.col; ++j)
			cout<<d.Array[i*d.col+j]<<"\t"; //注意地址求法
		cout<<endl;
	}
	cout<<endl;
	return output;
}

Douary operator+(const Douary &d1,const Douary &d2)//两个矩阵相加,规则:对应位置上的元素相加
{
	//在此可以先判断d1和d2的行列是否相同,如果不相同可以报错退出,不做运算。本参考解答忽略了这一前提
	Douary d(d1.row,d1.col);
	for(int i=0; i<d1.row; ++i)
	{
		for(int j=0; j<d1.col; ++j)
			d.Array[i*d1.col+j]=d1.Array[i*d1.col+j]+d2.Array[i*d1.col+j];
	}
	return d;
}

Douary operator-(const Douary &d1,const Douary &d2)//两个矩阵相减,规则:对应位置上的元素相减
{
	//在此可以先判断d1和d2的行列是否相同,如果不相同可以报错退出,不做运算。本参考解答忽略了这一前提
	Douary d(d1.row,d1.col);
	for(int i=0; i<d1.row; ++i)
	{
		for(int j=0; j<d1.col; ++j)
			d.Array[i*d1.col+j]=d1.Array[i*d1.col+j]-d2.Array[i*d1.col+j];
	}
	return d;
}
bool Douary::operator ==(const Douary &d)//判断两个矩阵是否相等,即对应位置上的所有元素是否相等
{
	if(row!=d.row||col!=d.col) return false;
	bool eq = true;
	for(int i=0; i<row; ++i)
	{
		for(int j=0; j<col; ++j)
			if (Array[i*col+j]!=d.Array[i*col+j]) 
			{
				eq=false;
				break;
			}
			if (!eq) break;
	}
	return eq;
}

int main()
{
	Douary d1(2,3),d2(2,3);
	cout<<"输入d1(2,3):"<<endl;
	cin>>d1;
	cout<<"输入d2(2,3):"<<endl;
	cin>>d2;
	cout<<"d1="<<endl;
	cout<<d1;
	cout<<"d2="<<endl;
	cout<<d2;
	cout<<"d1+d2="<<endl;
	Douary d3=(d1+d2);
	cout<<d3;
	cout<<"d1-d2="<<endl;
	cout<<(d1-d2);
	cout<<"d1"<<((d1==d2)?"==":"!=")<<"d2"<<endl;
	system("pause");
	return 0;
}

  还看见有的同学除了重载输出(ostream &operator<<(ostream &output, Douary &d))时用双重循环外,其余的函数中只用单重循环实现,例如operate+的实现:

Douary operator+(const Douary &d1,const Douary &d2)
{
	Douary d(d1.row,d1.col);
	for(int i=0; i<d1.row*d1.col; ++i)
	{
		d.Array[i]=d1.Array[i]+d2.Array[i];
	}
	return d;
}
  这也是一个很好的解决办法,对应位置上的值相加即可。只要输出时让用户看着是二维的样子即可,用户才不关心内部的实现呢。这种“欺里瞒外”的方法值得推荐。这要谴责,原题中要让实现二维数组功能,却偏给出个指向int的指针就已经带头这么干了。


<本文完>

目录
相关文章
|
人工智能 计算机视觉
教程 |【阿里云.人脸识别】Access Key ID 和 Access Key Secret 查看方法
本章主要介绍阿里云.人脸识别 Access Key ID 和 Access Key Secret 查看方法。
|
机器学习/深度学习 自然语言处理 前端开发
深度学习-[源码+数据集]基于LSTM神经网络黄金价格预测实战
深度学习-[源码+数据集]基于LSTM神经网络黄金价格预测实战
451 0
STM32速成笔记(六)—定时器
本文介绍了定时器的概念,作用。针对STM32F1的通用定时器做了详细介绍。此外,介绍了PWM的概念,用途以及STM32F1的PWM,给出了PWM频率的计算方法。最后通过介绍利用定时器的更新中断和PWM这两种方法实现呼吸灯,展示了定时器和PWM的配置步骤,并给出了详细的程序设计。另外,介绍了利用定时器实现按键长短按的检测方法。
424 0
STM32速成笔记(六)—定时器
|
传感器 监控 安全
物联网在教育中的应用
物联网对教育机构产生了重大影响。教育机构正在选择物联网生态系统,并利用从增强现实到云计算的各种技术
|
存储 Android开发
方法:一键把一堆手机号码一次性快速导入手机通讯录
手机是人们日常沟通常用的工具,所以自然就要用到手机里面的通讯录联系。因此我们常要把别人的号码存入到手机通讯录里面,如果只是存五个十个那就动动手指就可以了。但是如果你想存把一个电脑excel表格里面的几百个、几千个、几万个等数量级别的联系人一键导入手机通讯录,显然手动一个个来存入是不现实的。我这里演示,通过借助网上常见的便捷工具软件,金芝号码提取导入助手,代替你手动工作来快速完成这个工作,如何一键把一堆手机号码一次性快速导入手机通讯录,省事省时省力。下面做个操作过程的图文讲解。
4584 0
方法:一键把一堆手机号码一次性快速导入手机通讯录
|
域名解析 网络协议 大数据
阿里云注册域名使用教程
阿里云注册域名使用教程(图文教程)
798 0
|
弹性计算 运维 数据可视化
阿里云混合云管理平台发布 帮您管好云
6月9日, 在2020阿里云线上峰会上阿里云混合云战略正式发布:全栈建云、智能管云、极致用云。同步发布专有云敏捷版(Apsara Stack Agility)、 混合云管理平台(Apsara Uni-manager)以及下一代企业级一站式DevOps平台“云效”三大新品。
3107 0
阿里云混合云管理平台发布 帮您管好云
|
存储 弹性计算 Linux
阿里云发布第七代云服务器ECS,整机算力提升160%
2020年6月9日,阿里云重磅发布第七代ECS企业级高主频实例以及新一代弹性裸金属云服务器,目前已启动邀测。
阿里云发布第七代云服务器ECS,整机算力提升160%
|
编解码 安全 双11
揭秘“飞天”的24小时:马云真正的“核武器”
中国社会正在经历着巨大的商业变革,而巨大的商业变革也伴随着巨大的技术进步。阿里在对中国以至全球电子商务生态产生巨大影响的同时,背后的核心技术:云计算。将会怎样的影响未来?
11325 0
|
弹性计算 负载均衡 容灾
一文告诉你什么是NAT网关
NAT网关(NAT Gateway)是一款企业级的公网网关,提供NAT代理(SNAT和DNAT)、高达10Gbps级别转发能力以及跨可用区的容灾能力。
3319 0