类的使用 离散
要求:使用类来实现集合的交 并 补 差 对称差
先声明一个学生类
class Student
{
private:
int m_uiId;
public:
Student();
Student(int id);
Student(const Student & student);
Student & operator=(const Student & student);
bool operator==(const Student & student) const;
bool operator!=(const Student & student) const;
int GetID() const { return m_uiId; }
};
声明一个学生类 存有id
学生类的定义
Student::Student() {
srand(time(0));
int i=rand();
i=i%20;
m_uiId=i;
};
Student::Student(int id) {
m_uiId=id;
}
Student::Student(const Student &student) {
m_uiId=student.GetID();
};
Student & Student::operator=(const Student &student) {
m_uiId=student.GetID();
return *this;
};
bool Student::operator==(const Student &student) const {
if(student.GetID()==m_uiId){
return true;
}
else{
return false;
}
};
bool Student::operator!=(const Student &student) const {
if(student.GetID()==m_uiId){
return false;
}
else {
return true;
}
};
两个构造函数:1.Student::Student(int id) { m_uiId=id; }
实现传入参数保证id的准确性
2.Student::Student() { srand(time(0)); int i=rand(); i=i%20; m_uiId=i; };
默认构造函数,通过rand()
对于学生的id 进行赋一个初值,省去了想编号的烦恼 但rand()
在调用时已经是一个固定值,需要一个随机种子来改变他的数值,这里我们用srand(time(0))
来实现随机种子,不同的时间产生的种子不一样,id自然就不同吗,为了控制随机数在想要的范围内,通过对数值求余实现:i=i%20
复制构造函数:Student::Student(const Student &student) { m_uiId=student.GetID();
};传入一个参数,这个参数是一个对象,通过把传过来的对象的id赋值给本身的id实现复制
重载函数:1.Student & Student::operator=(const Student &student) { m_uiId=student.GetID(); return *this; };
重载赋值,通过把参数的id赋值给本身的私有数据实现赋值
2.bool Student::operator==(const Student &student) const { if(student.GetID()==m_uiId){ return true; } else{ return false; } };
重载 == 它本身的意义就是比较是否相等,相等就返回true,不相等就返回flase,所以我们只需要比较一下对象的id是否相等就可以实现‘==’的功能
bool Student::operator!=(const Student &student) const {
if(student.GetID()==m_uiId){
return false;
}
else {
return true;
}
};
这里的意义也是一样,重载‘!=’
int GetID() const { return m_uiId; }
这个就没什么好说的的,在主函数中不能访问私有数据,通过函数访问,以便于判断是否相等
第二个类
class StudentSet
{
private:
vector<Student> m_vecData;
public:
StudentSet();
StudentSet(const StudentSet & studentset);
StudentSet & operator=(const StudentSet & studentset);
bool Insert(const Student student);
bool Remove(const int id);
StudentSet Union(const StudentSet & studentset) const;
StudentSet InterSect(const StudentSet & studentset) const;
StudentSet Difference(const StudentSet & studentset) const;
StudentSet Complement() const;
StudentSet SymDifference(const StudentSet & studentset) const;
bool IsEmpty() const;
void Clear();
void Output() const;
};
通过一个类,里面是vector,一个动态数组,便于生成集合
函数定义
StudentSet::StudentSet() {
};
StudentSet::StudentSet(const StudentSet &studentset) {
int a=studentset.m_vecData.size();
for (int i = 0; i < a; ++i) {
m_vecData.push_back(studentset.m_vecData[i]);
}
};
StudentSet & StudentSet::operator=(const StudentSet &studentset) {
m_vecData.clear();
int a=studentset.m_vecData.size();
for (int i = 0; i < a; ++i) {
m_vecData.push_back(studentset.m_vecData[i]);
}
return *this;
};
bool StudentSet::Insert(const Student student) {
vector<Student>::iterator iter=find(m_vecData.begin(),m_vecData.end(),student);
if(iter==m_vecData.end()){
m_vecData.push_back(student);
return true;
}
else {
return false;
}
}
bool StudentSet::Remove(const int id) {
Student a(id);
vector<Student>::iterator iter=find(m_vecData.begin(),m_vecData.end(),a);
if(iter==m_vecData.end()){
return false;
}
else{
m_vecData.erase(iter);
return true;
}
}
StudentSet StudentSet::Union(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
res.m_vecData.push_back(m_vecData[i]);
}
for (int i = 0; i < studentset.m_vecData.size(); ++i) {
if(find(res.m_vecData.begin(),res.m_vecData.end(),studentset.m_vecData[i])==res.m_vecData.end()){
res.m_vecData.push_back(studentset.m_vecData[i]);
}
}
return res;
}
StudentSet StudentSet::InterSect(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if (find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])!=studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
return res;
}
StudentSet StudentSet::Difference(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if(find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])==studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
return res;
}
StudentSet StudentSet::Complement() const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i <=IDMAX; ++i) {
Student a(i);
if(find(m_vecData.begin(),m_vecData.end(),a)==m_vecData.end()){
res.m_vecData.push_back(a);
}
}
return res;
}
StudentSet StudentSet::SymDifference(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if(find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])==studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
for (int i = 0; i < studentset.m_vecData.size(); ++i) {
if(find(m_vecData.begin(),m_vecData.end(),studentset.m_vecData[i])==m_vecData.end()){
res.m_vecData.push_back(studentset.m_vecData[i]);
}
}
return res;
}
bool StudentSet::IsEmpty() const {
if (m_vecData.empty())
return true;
else return false;
}
void StudentSet::Clear() {
m_vecData.clear();
}
void StudentSet::Output() const {
for (int i = 0; i < m_vecData.size(); ++i) {
cout<<m_vecData[i].GetID()<<endl;
}
这个类的定义比较多,一个一个解释吧
1.
StudentSet::StudentSet() {
};
StudentSet::StudentSet(const StudentSet &studentset) {
int a=studentset.m_vecData.size();
for (int i = 0; i < a; ++i) {
m_vecData.push_back(studentset.m_vecData[i]);
}
};
这两个是构造函数,第一个就是单纯的一个构造函数,便于在主函数中定义对象,第二个是复制构造函数,通过传进来的参数进行赋值,将参数与本身进行赋值,这里的m_vecData.push_back(studentset.m_vecData[i]);
是插入动态数组,每一个学生类都是一个对象,插入到动态数组中去,这样就可以实现两个对象的复制
StudentSet & StudentSet::operator=(const StudentSet &studentset) {
m_vecData.clear();
int a=studentset.m_vecData.size();
for (int i = 0; i < a; ++i) {
m_vecData.push_back(studentset.m_vecData[i]);
}
return *this;
};
这也可以理解为一个复制,因为‘=’本身的意义就是将后面赋值给前面,原理相同,不多做解释了
这里返回*this,是因为这不是一个构造函数,而是一个类的函数,返回这个本身,函数调用的时候就会返回他自己,赋值或者判断是否相等都可以
因为是赋值,需要把动态数组中原有的数据清理掉,所以用 .clear()。
bool StudentSet::Insert(const Student student) {
vector<Student>::iterator iter=find(m_vecData.begin(),m_vecData.end(),student);
if(iter==m_vecData.end()){
m_vecData.push_back(student);
return true;
}
else {
return false;
}
}
这是一个插入的函数,vector<Student>::iterator iter=find(m_vecData.begin(),m_vecData.end(),student);
这个是一个函数,vector里面的find函数,(其实我也不是很懂 )他返回的是一个迭代器,第一个参数指的是检索的开头,第二个是检索的结尾,第三个参数是需要检索的内容,如果找到就返回找到的那个迭代器,如果没找到就返回检索的结尾,所以我们需要find函数来寻找这个动态数组中有没有要插入的元素,有就不插入,没有就插入,‘==’在上一个类中已经定义完成了,这是一个布尔类型的函数,成功插入就返回true,本身就有就返回flase
bool StudentSet::Remove(const int id) {
Student a(id);
vector<Student>::iterator iter=find(m_vecData.begin(),m_vecData.end(),a);
if(iter==m_vecData.end()){
return false;
}
else{
m_vecData.erase(iter);
return true;
}
}
删除函数,原理相同,如果有就返回true,并删掉这个元素,没有就返回flase,通过删除迭代器实现删除元素,这里我们可以把迭代器理解为指针,删除迭代器理解为,把指向这个元素的指针指向下一个,变相实现删除功能
StudentSet StudentSet::Union(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
res.m_vecData.push_back(m_vecData[i]);
}
for (int i = 0; i < studentset.m_vecData.size(); ++i) {
if(find(res.m_vecData.begin(),res.m_vecData.end(),studentset.m_vecData[i])==res.m_vecData.end()){
res.m_vecData.push_back(studentset.m_vecData[i]);
}
}
return res;
}
并集函数,实现并集并不是把两个动态数组合并,我们需要判断两个动态数组中有没有相同的元素,原理:先创造一个动态数组,(创造动态数组的时候需要先清空一下,防止有垃圾数据)把第一个全部塞进去,检索第二个,如果第一个中已经有,就不插入,没有就插入,最后返回这个对象
StudentSet StudentSet::InterSect(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if (find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])!=studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
return res;
}
交集,寻找两个数组中的相同元素,如果第一个中有第二个的元素,就把这个元素插入到新建的数组中,最后返回这个数组
StudentSet StudentSet::Difference(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if(find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])==studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
return res;
}
差集,比如A(1,2,3) B(2,3,4) 那么A-B=(1)
这里是用本身减去参数,所以我们在第一个中检索第二个,有就把他删除,没有就插入另一个数组中去,最后返回这个新数组
StudentSet StudentSet::Complement() const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i <=IDMAX; ++i) {
Student a(i);
if(find(m_vecData.begin(),m_vecData.end(),a)==m_vecData.end()){
res.m_vecData.push_back(a);
}
}
return res;
}
补集:在全部中寻找除了数组中的数
这里的Student a(i);
通过第一个类的构造函数,构造出不同id的学生,即为全部,再寻找,如果数组中有就不插入,反之,最后返回新的数组
StudentSet StudentSet::SymDifference(const StudentSet &studentset) const {
StudentSet res;
res.m_vecData.clear();
for (int i = 0; i < m_vecData.size(); ++i) {
if(find(studentset.m_vecData.begin(),studentset.m_vecData.end(),m_vecData[i])==studentset.m_vecData.end()){
res.m_vecData.push_back(m_vecData[i]);
}
}
for (int i = 0; i < studentset.m_vecData.size(); ++i) {
if(find(m_vecData.begin(),m_vecData.end(),studentset.m_vecData[i])==m_vecData.end()){
res.m_vecData.push_back(studentset.m_vecData[i]);
}
}
return res;
}
对称差:例如:A(1,2,3) B(2,3,4)(忘了怎么表示 )
A对称差B=(1,4)
原理:在第一个数组中寻找第二个数组中没有的元素插入新数组,同理在第二个数组中寻找第一个数组没有的元素,最后返回新数组
bool StudentSet::IsEmpty() const {
if (m_vecData.empty())
return true;
else return false;
}
void StudentSet::Clear() {
m_vecData.clear();
}
void StudentSet::Output() const {
for (int i = 0; i < m_vecData.size(); ++i) {
cout<<m_vecData[i].GetID()<<endl;
}
最后这三个函数
1.判断元素是否为空,对于vector,如果为空就返回真,反之
.empty(),就是这样的一个函数
2.Clear()就是清空数组,没什么好说的
3.Output,通过遍历数组,一个一个cout,就可以实现展示动态数组
最后放一下主函数:
int main()
{
srand((unsigned int)time(NULL));
StudentSet set1, set2, set3;
set1.Clear();
set2.Clear();
set3.Clear();
for (unsigned int i = 0; i < 5; i++)
{
Student tmpstudent(i);
set1.Insert(tmpstudent);
}
set1.Output();
system("pause");
Student tmpstudent1( 3);
cout << set1.Insert(tmpstudent1) << endl;
system("pause");
Student tmpstudent2(10);
cout << set1.Insert(tmpstudent2) << endl;
system("pause");
for (unsigned int i = 7; i < 12; i++)
{
Student tmpstudent(i);
set2.Insert(tmpstudent);
}
set2.Output();
system("pause");
set3 = set1.Union(set2);
set3.Output();
system("pause");
set3 = set1.InterSect(set2);
set3.Output();
system("pause");
set3 = set1.Difference(set2);
set3.Output();
system("pause");
set3 = set3.Complement();
set3.Output();
system("pause");
set3 = set1.SymDifference(set2);
set3.Output();
system("pause");
return 0;
}