第14周-任务1-数组类的构造

简介: 【关于题目】数组是几乎所支持的组织数据的方法。C和C++对数组类型提供了内置支持,使我们利用数组实现软件中需要的各种实用的功能。但是,这种支持仅限于用来读写单个元素的机制。C++不支持数组的抽象abstraction,也不支持对整个数组的操作。例如:把一个数组赋值给另外一个数组,对两个数组进行相等比较或者想知道数组的大小size,等等。对C++而言,数组是从C语言中继承来的,它反映了数据与

【关于题目】数组是几乎所支持的组织数据的方法。C和C++对数组类型提供了内置支持,使我们利用数组实现软件中需要的各种实用的功能。但是,这种支持仅限于用来读写单个元素的机制。C++不支持数组的抽象abstraction,也不支持对整个数组的操作。例如:把一个数组赋值给另外一个数组,对两个数组进行相等比较或者想知道数组的大小size,等等。对C++而言,数组是从C语言中继承来的,它反映了数据与对其进行操作的算法的分离,有浓厚的过程化程序设计的特征。数组并不是C++语言的一等公民。所以在实际项目中,对一个C++程序员,更多的是使用标准库中提供的Vector类型实现数组功能。这个任务也将从面向对象角度重新审视和理解数组,进而扫清自学Vector等标准类中可能存在的障碍。

【题目】建立专门的数组类处理有关数组的操作
在下面代码的基础上,完成支持数组操作的类的设计,增强C++内置数组类型功能。

class MyArray
{
private:
	int *arr;		//用于存放动态分配的数组内存首地址
	int size;		//数组大小
public:
	MyArray(int sz=50);
	MyArray(int a[],int sz);	//由一个内置类型的数组初始化
	MyArray(const MyArray &A);	//复制构造函数
	~MyArray(void);				//析构函数,注意释放空间
	MyArray&operator =(const MyArray &A); //重载“=”使得数组对象可以整体赋值
	int& operator[](int i);		//重载[],使得Array对象也可以如C++普通数组一样,用a[i]形式取出值【选做】
	bool operator == (MyArray& A);	//重载==,使得Array对象能整体判断两个数组是否相等(size相等且对应元素相等)
	MyArray operator + (MyArray& A);	//重载+,使两个Array对象可以整体相加(前提大小相等)【选做】
	friend ostream& operator << (ostream& out,MyArray& A);	//重载<<,输出数组
	int GetSize(void)const;	//取数组大小;
	void Resize(int sz);	//修改数组的大小,如果sz大于数组的原大小,增加的元素初始为;sz小于数组的原大小,舍弃后面的元素【选做】
};

int main()
{	int a[10]={1,2,3,4,5,6,7,8,9,10};
	int b[10]={4,5,6,7,8,9,10,11,12,13};
	MyArray arr1(a,10);
	MyArray arr2(b,10);
	MyArray arr3(10);
	cout<<arr3;
	arr3 = arr1 +arr2;
	cout<<arr3;
	arr3.Resize(20);
	cout<<arr3;
	arr3.Resize(5);
	cout<<arr3;
	system("pause");
	return 0;
} 


【参考解答】

#include <iostream> 
using namespace std;
class MyArray
{
private:
	int *arr;		//用于存放动态分配的数组内存首地址
	int size;		//数组大小
public:
	MyArray(int sz=50);
	MyArray(int a[],int sz);	//由一个内置类型的数组初始化
	MyArray(const MyArray &A);	//复制构造函数
	~MyArray(void);				//析构函数,注意释放空间
	MyArray&operator =(const MyArray &A); //重载“=”使得数组对象可以整体赋值
	int& operator[](int i);		//重载[],使得Array对象也可以如C++普通数组一样,用a[i]形式取出值【选做】
	bool operator == (MyArray& A);	//重载==,使得Array对象能整体判断两个数组是否相等(size相等且对应元素相等)
	MyArray operator + (MyArray& A);	//重载+,使两个Array对象可以整体相加(前提大小相等)【选做】
	friend ostream& operator << (ostream& out,MyArray& A);	//重载<<,输出数组
	int GetSize(void)const;	//取数组大小;
	void Resize(int sz);	//修改数组的大小,如果sz大于数组的原大小,增加的元素初始为;如果sz大于数组的原大小,舍弃后面的元素【选做】
};

//以下为类成员函数的定义

//构造函数
MyArray::MyArray(int sz)
{
	if(sz<=0)
	{
		cout<<"invalid Array Size!";
		exit(1);
	}
	size=sz;    		//将元素个数赋值给变量size
	arr=new int[size];//动态分配内存,将size个int类型的元素空间分配出来
	for(int i=0; i<size; ++i)
		*(arr+i)=0;
}

MyArray::MyArray(int a[],int sz)
{
	if(sz<=0)
	{
		cout<<"invalidArraySize";
		exit(1);
	}
	size=sz;//将元素个数赋值给变量size
	arr=new int[size];//动态分配内存,将size个int类型的元素空间分配出来
	for(int i=0; i<size; ++i)
		*(arr+i)=*(a+i);
}

//析构函数
MyArray::~MyArray(void)
{
	delete []arr;
}

//复制构造函数
MyArray::MyArray(const MyArray& A)
{
	//从对象A取得数组大小,并赋给当前对象成员
	int n=A.size;
	size=n;
	//为对象申请内存并进行出错检测
	arr=new int[n];
	//从对象A复制数组元素到本对象
	int *srcptr=A.arr;//X.arr是对象A的数组首地址
	int *destptr=arr;//arr是本对象中的数组首地址
	while(n--)
	{
		*destptr=*srcptr;
		destptr++;
		srcptr++;
	}
}

//重载'='
MyArray& MyArray::operator =(const MyArray &A)
{
	int n=A.size;//取A数组的大小
	//如果本对象中的数组大小和A不同,则删除数组原有的内存,然后重新分配
	if (size!=n)
	{
		delete []arr;
		arr=new int[n];
		size=n;
	}

	//从rhs向本对象复制元素
	int* destptr=arr;
	int* srcptr=A.arr;
	while(n--)
	{
		*destptr=*srcptr;
		destptr++;
		srcptr++;
	}
	return *this;//返回当前对象的引用
}

//重载[]
int &MyArray::operator[](int n)
{
	if(n<0||n>size-1)
	{
		cout<<"indexOutOfRange"<<endl;
		exit(1);
	}
	return arr[n];
}

bool MyArray::operator == (MyArray& A)
{
	bool eq=true;
	int n=A.size;	//取A数组的大小
	if (size!=n)   //大小是否一致
	{
		eq=false;
	}
	else
	{
		int* destptr=arr;
		int* srcptr=A.arr;
		while(n--)
		{
			if(*destptr!=*srcptr)
			{
				eq=false;
				break;
			}
			destptr++;
			srcptr++;
		}
	}
	return eq;//返回当前对象的引用
}

MyArray MyArray::operator + (MyArray& A)
{
	int n=A.size;	//取A数组的大小
	if (size!=n)   //大小不一致不能相加
	{
		cout<<"not same size for add!"<<endl;
		exit(1);
	}
	MyArray a(n);  //指定size的数组

	for (int i = 0; i < size; i++)
	{
		a[i]=arr[i]+A[i];
	}
	return a;//返回当前对象的引用
}

ostream& operator << (ostream& out, MyArray& A)
{
	for (int i = 0; i < A.size; i++)
	{
		out<<A[i]<<'\t';
	}
	out<<endl;
	return out;
}

//取当前数组大小
int MyArray::GetSize(void)const
{
	return size;
}

//将数组大小修改为sz
void MyArray::Resize(int sz)
{
	if(sz<=0)
	{
		cout<<"invalidArraySize"<<endl;
		exit(1);
	}
	if(sz==size)
		return;
	int *newlist=new int[sz];
	for (int i = 0; i < sz; i++)
	{
		*(newlist+i)=0;
	}
	int n=(sz<=size)?sz:size;
	int *srcptr=arr;
	int *destptr=newlist;
	while(n--)
	{
		*destptr=*srcptr;
		destptr++;
		srcptr++;
	}
	delete []arr;
	arr=newlist;
	size=sz;
}

int main()
{
	int a[10]={1,2,3,4,5,6,7,8,9,10};
	int b[10]={4,5,6,7,8,9,10,11,12,13};
	MyArray arr1(a,10);
	MyArray arr2(b,10);
	MyArray arr3(10);
	cout<<arr3;
	arr3 = arr1 +arr2;
	cout<<arr3;
	arr3.Resize(20);
	cout<<arr3;
	arr3.Resize(5);
	cout<<arr3;
	system("pause");
	return 0;
} 

【任务扩展一(选做)】规定MyArray只能处理元素为整型的数据未免太弱了,请设计成模板类,使之适应各种类型(事实上,C++增加的标准类对些类情况均设计成了模板类)。
【任务扩展二(选做)】可以施加于数组的操作还有很多,例如最经典的排序,还有求最大、最小、查找某一元素、截取其中的片段(取从第5个互第10个之间的所有元素,可以形成新的数组对象)、向量乘法,……。将这些操作构造为类的成员函数,开始拓展之旅吧!
目录
相关文章
|
10月前
|
前端开发 JavaScript UED
处理 React 运行时中的错误和异常
【10月更文挑战第25天】在React运行时中,有效地处理错误和异常对于确保应用的稳定性和用户体验至关重要。
|
存储 机器学习/深度学习 物联网
基于重要性加权的LLM自我改进:考虑分布偏移的新框架
本文提出一种新的大型语言模型(LLM)自我改进框架——基于重要性加权的自我改进(IWSI),旨在优化自动生成数据的质量。通过引入DS权重指标衡量数据的分布偏移程度(DSE),该方法不仅能确保答案正确性,还能过滤掉那些虽正确但分布上偏离较大的样本,以提升自我训练的效果。IWSI使用一个小的有效数据集来估算每个自生成样本的DS权重,并据此进行筛选。实验结果显示,相比于仅依赖答案正确性的传统方法,IWSI能更有效地提高LLM在多种任务上的表现。特别是在数学问题解答任务上,相较于基线方法,IWSI带来了显著的性能提升,证实了过滤高DSE样本的重要性及该方法的有效性。
261 0
基于重要性加权的LLM自我改进:考虑分布偏移的新框架
|
编译器 C++
c++的学习之路:22、多态(1)
c++的学习之路:22、多态(1)
80 0
c++的学习之路:22、多态(1)
|
存储 SQL 监控
ADBPG&Greenplum成本优化问题之ADB PG的数据库管控的定义如何解决
ADBPG&Greenplum成本优化问题之ADB PG的数据库管控的定义如何解决
110 2
|
Ubuntu Linux Apache
Linux基础命令---htdigest建立和更新apache服务器摘要
htdigest htdigest指令用来建立和更新apache服务器用于摘要认证的存放用户认证信息的文件。 此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS。 1、语法 htdigest [-c] passfile realm username 2、...
1146 0
|
云安全 存储 运维
如何成为一名专业云渗透测试工程师
从宏观层面来看,新基建成为中国经济热词,政府和企业业务上云全面提速,随着云计算技术的快速发展,云安全问题已成为重点关注的领域。但从安全角度来看,这也意味着安全态势变得更加复杂,安全的范畴也变得更加广泛,漏洞存在于每个地方、攻击可以由世界任何一个地方发起,对于网络安全的准确预测成为保障安全的关键前提。
|
存储 算法
leetcode第49题
时间复杂度:两层 for 循环,再加上比较字符串,如果字符串最长为 K,总的时间复杂度就是 O(n²K)。 空间复杂度:O(NK),用来存储结果。 解法一算是比较通用的解法,不管字符串里边是大写字母,小写字母,数字,都可以用这个算法解决。这道题的话,题目告诉我们字符串中只有小写字母,针对这个限制,我们可以再用一些针对性强的算法。 下边的算法本质是,我们只要把一类的字符串用某一种方法唯一的映射到同一个位置就可以。
253 0
leetcode第49题
五分钟带你玩转Elasticsearch(六)看了这篇文档,教你无脑安装logstash
五分钟带你玩转Elasticsearch(六)看了这篇文档,教你无脑安装logstash
172 0
五分钟带你玩转Elasticsearch(六)看了这篇文档,教你无脑安装logstash
11月8日科技联播:特斯拉宣布其CFO接替马斯克担任董事长;苹果拒不和解要和高通对簿公堂
马斯克让位,特斯拉现任CFO接任董事长;苹果拒不和解,要和高通对簿公堂,70亿美元专利费矛盾激化;联想公布二季度营收,创四年来新高;游戏审批遇阻,腾讯决定削减营销预算节省开支,一起来看今天的科技快讯!
1430 0
|
前端开发 Java 数据库
SpringBoot实现上传下载(一)
最近在学Springboot相关知识,这次用Springboot做了一个上传下载的功能,项目demo 上传一个法律名及其发布的年份等信息,然后还要能上传一个pdf文件(这里限制下上传的后缀名就可以),上传之后,点击操作中的下载,下载对应的pdf文件。
2194 0