通过类来实现集合的交 并 补 差 对称差

类的使用 离散

要求:使用类来实现集合的交 并 补 差 对称差
先声明一个学生类

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;
}
  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.℡.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值