【C++】2、集合

定义并实现一个整数集合类int_set,集合类中cur_size表明当前集合中有几个整数,集合中最多含max_size个整数,存放集合元素的数组是动态的。要求提供的方法有:

(1) 增加一个整数到集合中;
(2)从集合中去掉一个元素;
(3)判断一个元素是否在集合中;
(4)重载<<运算法,输入集合;重载>>运算符输出集合;
(5)分别实现集合的交、并、差运算。

int_set.h :

#pragma once
#include<iostream>
using namespace std;
class int_set
{	
private:
	int cur_size;//实际长度
	int max_size;//最大长度
	int* num;
public:
	int_set(int initialCapacity = 10);
	int_set(const int_set&);
	~int_set();

	bool empty()const;
	int size()const;
	bool contain(int element)const;
	int& get(int theIndex)const;
	void add(int element);
	void remove(int element);
	void output()const;

	friend istream& operator>>(istream&,int_set&);
	friend ostream& operator<<(ostream&, const int_set&);	void operator=(const int_set&);
	int_set& operator=(int_set&);

	int_set inter_set(int_set&);//求交集
	int_set union_set(int_set&);//求并集
	int_set differ_set(int_set&);//求差集
};

int_set.cpp :

#include "int_set.h"
int_set::int_set(int initialCapacity)
{
	if (initialCapacity < 1) {
		throw"集合长度要大于0\n";
	}
	max_size = initialCapacity;
	num = new int[max_size];
	cur_size = 0;
}

int_set::int_set(const int_set& set) {
	max_size = set.max_size;
	cur_size = set.cur_size;
	num = new int[max_size];
	copy(set.num, set.num + cur_size, num);
}

int_set::~int_set()
{
	delete[]num;
}

bool int_set::empty() const
{	
	return cur_size == 0;
}

int int_set::size() const
{
	return cur_size;
}

bool int_set::contain(int element) const
{
	for (int i = 0;i < cur_size;i++) {
		if (*(num + i) == element) {
			return true;
		}
	}
	return false;
}

int& int_set::get(int theIndex) const
{
	if (theIndex < 0 || theIndex >= cur_size) {
		throw "索引错误";
}
	return *(num + theIndex);
}

void int_set::add(int element)
{

	if (cur_size == max_size) {
		throw"集合已满\n";
	}
	if (contain(element)) {
		throw "集合已存在元素\n";
	}
	*(num + cur_size) = element;
	cur_size++;
}

void int_set::remove(int element)
{
	if (empty()) {
		throw"集合为空\n";
	}
	if (!contain(element)) {
		throw"该集合不存在该元素\n";
	}
	int* p = new int[max_size],n=0;
	for (int i = 0;i < cur_size;i++) {
		if (*(num + i) != element) {
			*(p+n) = *(num + i);
			n++;
		}
	}
	delete[]num;
	cur_size--;
	num = p;
	
}

void int_set::output() const
{
	for (int i = 0;i < cur_size;i++) {
		cout << *(num + i)<<" ";
	}
}

int_set& int_set::operator=(int_set&set)
{
	if (this != &set) {
		if (this != NULL)
			delete[]num;
		max_size = set.max_size;
		cur_size = set.cur_size;
		num = new int[max_size];
		copy(set.num, set.num + cur_size, num);
	}
	return *this;
}

int_set int_set::inter_set(int_set& set)
{
	int n = min(cur_size, set.cur_size);
	int_set s(n);
	for (int i = 0;i < cur_size;i++) {
		if (set.contain(*(num + i))) {
			s.add(*(num + i));
		}
	}
	return s;
}

int_set int_set::union_set(int_set&set)
{
	
	int n = cur_size + set.cur_size;
	int_set s(n);
	for (int i = 0;i < cur_size;i++) {
		s.add(*(num + i));
	}
	for (int i = 0;i < set.cur_size;i++) {
		if (!s.contain(*(set.num + i))) {
			s.add(*(set.num + i));
		}
	}
	return s;
}

int_set int_set::differ_set(int_set& set)
{
	int_set s = inter_set(set);
	int n = this->size() - s.size();
	int_set differ(n);
	for (int i = 0;i < cur_size;i++) {
		if (!s.contain(*(num + i)) ){

			differ.add(*(num + i));
		}
	}
	return differ;
	
}

/*
有参构造函数初始化时,要保证最大长度大于0;

添加元素时,判断集合是否满
集合是否存在该元素

删除元素时,判读集合是否为空
集合是否不存在该元素
*/

istream& operator>>(istream&in, int_set& set)
{
	int n, temp;
	cout << "请输入集合长度:";
	cin >> n;
	while (n--) {
		cout << "请输入要添加的元素:";
		in >> temp;
		set.add(temp);
	}
	return in;
}

ostream& operator<<(ostream& os, const int_set& set)
{
	for (int i = 0;i < set.cur_size - 1;i++) {
		os << *(set.num + i) << ",";
	}
	os << *(set.num + set.cur_size - 1);
	return os;
}

Test.cpp :

#include<iostream>
using namespace std;
#include"int_set.h"
int  main()
{
	try {
		int_set set1(-2);
	}
	catch ( const char* msg) {
		cout << msg;
	}
	int_set set(5);
	set.add(1);
	set.add(3);
	set.add(5);
	set.add(7);
	try {
		set.add(5);
	}
	catch (const char* msg) {
		cout << msg;
	}
	set.add(9);
	try {
		set.add(11);
	}
	catch (const char* msg) {
		cout << msg;
	}

	//删除操作
	try {
		set.remove(23);
	}
	catch (const char* msg) {
		cout << msg;
	}
	set.output();
	cout << "\n";
	set.remove(1);
	set.remove(3);
	set.remove(5);
	set.remove(7);
	set.remove(9);
	try {
		set.remove(5);
	}
	catch (const char* msg) {
		cout << msg;
	}
	/*
	理论上每一个add()、remove()都要用try、catch
	这里我为了简便,只有异常情况使用了
	*/

	int_set s1,s2;
	cin >> s1;
	cout << "s1 = { ";
	cout << s1<<"}\n";
	cin >> s2;
	cout << "s2 = { ";
	cout << s2 << "}\n";

	cout << "s1和s2的并集为:";
	cout<<s1.union_set(s2)<<"\n";
	cout << "s1和s2的交集为:";
	cout << s1.inter_set(s2) << "\n";
	cout << "s1和s2的差集为:";
	cout << s1.differ_set(s2) << "\n";
	return 0;
}


在这里插入图片描述

总结一下:今天遇到的问题困扰我很久,其实呢,当遇到指针时,要考虑重写复制构造函数和析构函数,还有重载赋值运算符。

在我写交集、并集和差集时,由于形参是类引用,不重写复制构造函数,就会导致申请的动态内存重复释放两次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值