要求
不能直接用STL,只能用数组,可以用algorithm的快排
至少包括:并集运算、交集运算、差集运算
其中s1 symmetric difference s2 = (s1 union s2) - (s1 intersect s2)
或= (s1 - s2) union (s2 - s1)
对称的差集运算(S1和S2并 – S1和S2的交集) (s1 - s2) union (s2 - s1)
初始化 初值 initialization 参数不合理也要抛出异常
Assignment 赋值
Insert 插入
Erase 元素 没有就不改集合,不算异常
isSubset 判断是否为另一个集合的子集 返回bool
Contain 集合是否包含某个整数
Print 输出集合的值{}括起来,元素按顺序输出,逗号分隔
Size 元素多少 capacity 预留空间
isEmpty isFull 满的时候再加要产生异常
Clear 清除所有元素
个人实现iSet未详尽考虑到的点
①在实现operator=的时候没有考虑到class a; a = a;
的时候会先释放掉a.ptr的内存再申请一块新的内存,这样会导致数据的丢失,因此如果a=a的情况下应该先对 传入的参数进行判定`this != &a
②依然是operator=,返回的类型应该返回引用值,虽然不返回引用值也是可行的,但是当无法进行链式编程,类似a = b = c的情况就无法实现,另外,如果只是值传递的话,会增加不必要的内存开销
③ 拷贝函数注意传入的参数也得用引用,如果不用引用的话,本身传入的参数是他的副本,副本又要拷贝一次类,这样会造成无限递归,导致栈溢出
测试代码
//----------------------------------------------------------------------
//
// Lab06Test.cpp : Test program for Lab 6.
//
//----------------------------------------------------------------------
#include <iostream>
using namespace std;
#include "iSet.h" // your header file for class iSet
int main(int argc, char** argv)
try
{
// ***** test for initialization *****
iSet s1{100}; // an integer set with 100 maximum elements
iSet s2{110}; // an integer set with 110 maximum elements
// ***** test for printing *****
cout << "Set s1 after initialization: " << endl;
s1.print(); // display set
cout << endl;
// ***** test for size *****
cout << "The number of elements in Set s1: " << s1.size() << endl;
cout << "The capacity of Set s1: " << s1.capacity() <<endl;
cout << endl << "Set s2 after initialization: " << endl;
s2.print(); // display set
cout << endl;
cout << "The number of elements in Set s2: " << s2.size() << endl;
cout << "The capacity of Set s2: " << s2.capacity() << endl;
cout << endl;
// ***** test for inserting *****
for (int i{200};i<220;i++) s1.insert(i); // insert 20 elements from 200 to 219
for (int i{190};i<215;i++) s2.insert(i); // insert 25 elements from 190 to 214
cout << "Set s1 after inserting: " << endl;
s1.print(); // display set
cout << endl;
cout << "The number of elements in Set s1: " << s1.size() << endl;
cout << "The capacity of Set s1: " << s1.capacity() << endl;
cout << endl << "Set s2 after inserting: " << endl;
s2.print(); // display set
cout << endl;
cout << "The number of elements in Set s2: " << s2.size() << endl;
cout << "The capacity of Set s2: " << s2.capacity() << endl;
cout << endl;
// ***** test for union *****
cout << "Union of two integer sets s1 and s2: " << endl;
s1.print(); // display set
cout << " 并 ";
s2.print(); // display set
cout << " = ";
iSet r1{s1.setUnion(s2)}; // compute union of two integer sets
r1.print(); // display union result
cout << endl;
cout << endl;
// ***** test for intersection *****
cout << "intersection of two integer sets s1 and s2: " << endl;
s1.print();
cout << " 交 ";
s2.print();
cout << " = ";
iSet r2{s1.setIntsection(s2)}; // compute intersection of two integer sets
r2.print();
cout << endl;
cout << endl;
// ***** test for difference *****
cout << "difference of two integer sets s1 and s2: " << endl;
s1.print();
cout << " 差 ";
s2.print();
cout << " = ";
iSet r3{s1.setDifference(s2)}; // compute difference of two integer sets
r3.print();
cout << endl;
cout << endl;
cout << "difference of two integer sets s2 and s1: " << endl;
s2.print();
cout << " 差 ";
s1.print();
cout << " = ";
iSet r4{s2.setDifference(s1)}; // compute difference of two integer sets
r4.print();
cout << endl;
cout << endl;
// ***** test for symmetric difference *****
cout << "symmetric difference of two integer sets s1 and s2: " << endl;
s1.print();
cout << " symmetric差 ";
s2.print();
cout << " = ";
iSet r5{s1.setSymmetricDifference(s2)}; // compute symmetric difference of two integer sets
r5.print();
cout << endl;
cout << endl;
// ***** test for assignment *****
cout << "Set s1 after assignment s1=s2: " << endl;
s1=s2;
s1.print();
cout << endl;
cout << endl;
// ***** test for "clear" *****
cout << "Set s2 after erasing all elements: " << endl;
s2.clear();
s2.print();
cout << endl;
cout << endl;
// ***** test for "isEmpty" *****
if (s1.isEmpty()) cout << "Set s1 is empty " << endl;
else cout << "Set s1 is NOT empty " << endl;
cout << endl;
if (s2.isEmpty()) cout << "Set s2 is empty " << endl;
else cout << "Set s2 is NOT empty " << endl;
cout << endl;
// ***** test for "isFull" *****
if (s1.isFull()) cout << "Set s1 is fully " << endl;
else cout << "Set s1 is NOT full " << endl;
cout << endl;
if (s2.isFull()) cout << "Set s2 is full " << endl;
else cout << "Set s2 is NOT full " << endl;
cout << endl;
// ***** test for "erase" *****
cout << "Set s1 after erasing an element 211 : " << endl;
s1.erase(211);
s1.print();
cout << endl;
cout << endl;
cout << "Set s1 after erasing an element 288 : " << endl;
s1.erase(288);
s1.print();
cout << endl;
cout << endl;
// ***** test for "contains" *****
int e{222};
if (s1.contains(e)) cout << e << " is a member of s1" << endl;
else cout << e << " is NOT a member of s1" << endl;
cout << endl;
e+=888;
if (s1.contains(e)) cout << e << " is a member of s1" << endl;
else cout << e << " is NOT a member of s1" << endl;
cout << endl;
// ***** test for "isSubset" *****
if (s1.isSubset(s2)) cout << "Set s2 is a subset of s1" << endl;
else cout << "Set s2 is NOT a subset of s1" << endl;
cout << endl;
cout << "Insert an element 888 into set s2 : " << endl;
s2.insert(888);
cout << "Set s2 : " << endl;
s2.print();
cout << endl;
cout << endl;
if (s1.isSubset(s2)) cout << "Set s2 is a subset of s1" << endl;
else cout << "Set s2 is NOT a subset of s1" << endl;
cout << endl;
// ***** test for exception throwing *****
cout << "insert 1000 elements from 1 to 999 into set s1 : " << endl;
for (int i{1};i<1000;i++)
s1.insert(i); // insert 1000 elements from 1 to 999
return 0;
}
// ***** exception handling *****
catch(iSet::bad_iSet bi) // catch exceptions related to integer set
{ switch (bi.errnum) // # of exceptions
{ case 1: cerr << "bad iSet: constructor parameter<1 , exit " << endl;
// error of constructor parameter
break;
case 2: cerr << "bad iSet: maximum elements reached(is Full), exit " << endl;
// overflow of integer set
break;
}
return 0;
}
头文件代码(基本要求)
#pragma once
#include<iostream>
class iSet
{
private:
int * ptr;
int capability;
int element;
void uni_sort();
public:
struct bad_iSet
{
int errnum;
};
iSet(int);
iSet(const iSet &);
~iSet();
//基本要求
int size()const;
int capacity()const;
void print()const;
void insert(int);
void erase(int);
void clear();
bool isEmpty()const;
bool isFull()const;
bool contains(int)const;
bool isSubset(iSet&)const;
//注意用引用减少内存开销
iSet setUnion(iSet&)const;
iSet setIntsection(iSet&)const;
iSet setDifference(iSet&)const;
iSet setSymmetricDifference(iSet&)const;
//补充
iSet& operator=(const iSet&);
int find(int,int,int)const;
};
实现代码(基本要求)
#include"iSet.h"
#include<iostream>
#include<algorithm>
using namespace std;
int iSet::find(int num,int up,int low = 0)const
{
if(up < low || up < 0 || low > element)
return -1;
int loc = (up + low) / 2;
if(ptr[loc] == num)
return loc;
else if(ptr[loc] > num)
return find(num,loc - 1, low);
else if(ptr[loc] < num)
return find(num,up, loc + 1);
}
iSet::iSet(int init_num)
{
if(init_num < 1)
{
bad_iSet bi;
bi.errnum = 1;
throw bi;
}
ptr = new int[init_num];
capability = init_num;
element = 0;
//初始化,申请内存,容量初始化,元素初始化
}
iSet::iSet(const iSet & S)
{
this->ptr = new int[capability];
this->capability = S.capability;
this->element = S.element;
for(int i = 0; i < S.element; i++)
this->ptr[i] = S.ptr[i];
}
iSet::~iSet()
{
delete[] ptr;//释放内存
}
int iSet::size()const
{
return element;
}
int iSet::capacity()const
{
return capability;
}
void iSet::print()const
{
cout << '{';
if(element > 0)
{
for(int i = 0; i < element - 1; i++)
cout << ptr[i]<<",";
cout << ptr[element - 1];
}
cout << '}';
}
void iSet::insert(int N)
{
//要用二分查找
if(capability == element)
{
bad_iSet bi;
bi.errnum = 2;
throw bi;
}
else if(element == 0)
{
ptr[element++] = N;
}
else if(find(N,element - 1) == -1)
{
ptr[element++] = N;
sort(ptr, ptr + element);
}
}
void iSet::erase(int N)
{
int loc = find(N,element - 1);
if(loc != -1 && loc < element)
{
ptr[loc] = ptr[--element];
sort(ptr, ptr + element);
}
}
void iSet::clear()
{
element = 0;
}
bool iSet::isEmpty()const
{
if(element == 0)
return true;
else
return false;
}
bool iSet::isFull()const
{
if(element == capability)
return true;
else
return false;
}
bool iSet::contains(int N)const
{
int loc = find(N,element - 1);
if(loc != -1 && loc < element)
return true;
else return false;
}
bool iSet::isSubset(iSet &S)const
{
if(this->element > S.element)
return false;
int bigloc = 0;
for(int i = 0; i < this->element; i++)
{
//按顺序排好,所以从小到大查就好了
for(int j = bigloc; j < S.element; j++)
{
if(this->ptr[i] == S.ptr[j])
bigloc = j + 1;
else if(this->ptr[i] < S.ptr[j])//this有一个数据小于S,而S后面的数据都大于this的这个数据,说明不包含
return false;
}
}
return true;
}
iSet iSet::setUnion(iSet& S)const //并集
{
iSet temp{S.capability + this->capability};
for(int i = 0; i < S.element; i++)
{
temp.insert(S.ptr[i]);
}
for(int i = 0; i < this->element; i++)
{
temp.insert(this->ptr[i]);
}
return temp;
}
iSet iSet::setIntsection(iSet& S)const //交集
{
iSet temp{((S.capability < this->capability) ? S.capability : this->capability)};
for(int i = 0; i < this->element; i++)
{
// cout << ptr[i] << endl;
// cout << S.find(this->ptr[i],S.element)<<endl;
if(S.find(this->ptr[i],S.element) != -1)//注意是在THIS集合找S的数据
temp.insert(this->ptr[i]);//找得到就插入,找不到不插入
}
return temp;
}
iSet iSet::setDifference(iSet& S)const //补集
{
iSet temp{this->capability};
for(int i = 0; i < this->element; i++)
if(S.find(this->ptr[i],S.element) == -1)
temp.insert(this->ptr[i]);
return temp;
}
iSet iSet::setSymmetricDifference(iSet& S)const
{
iSet s1{this->setUnion(S)};
iSet s2{this->setIntsection(S)};
iSet s3{s1.setDifference(s2)};
return s3;
}
iSet& iSet::operator=(const iSet& S)
{
//default copy错误
if(this != &S)
{
delete[] ptr;
ptr = new int[S.capability];
this->element = S.element;
this->capability = S.capability;
for(int i = 0; i < S.capability; i++)
this->ptr[i] = S.ptr[i];
}
return *this;
}
补充了一点STL的函数
zip下载
大致是这些内容
iSet operator+(iSet&)const;//union并集
iSet operator-(iSet&)const ;//dif差集
iSet operator*(iSet&)const ;//inter交集
iSet operator/(iSet&)const ;//sysmetric差
friend ostream& operator<<(ostream&,const iSet);//输出内部所有数据
friend istream& operator>>(istream&, iSet);//用>>运算符来插入数据
int find(int,int,int)const;//二分查找
int find(int)const;
void resize(int);//更改容量大小
int* begin()const;//return first element's point
int* end()const;//return last element's+1 point
int* upper_bound(int)const;//return element's point which is bigger than the num
更改日志
21-04-25 17:37 修正了重载运算符operator=在a = a
这种情况下把内存释放掉导致数据缺失的情况