c++入门笔记-set/multiset集合容器

基本概念

简介:所有元素都会在插入时自动被排序

本质:set/multiset属于关联式容器 底层结构是用二叉树实现

c++入门笔记-set/multiset集合容器_第1张图片

 

set和multiset区别:

set不允许容器中有重复的元素

multiset允许容器中有重复的元素 

注意⚠️:只要包含了set头文件就可以使用multiset

set构造和赋值操作

set st;  //默认构造

set(const set &st);  //拷贝构造

set& operator=(const set &st);  //重载等号操作符

#include 
using namespace std;
#include 

void printSet(const set&s){
    for(set::const_iterator it = s.begin();it != s.end();it++){
        cout << *it << " ";
    }
    cout <s1;
    //插入数据 只有insert方法
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(20);
    s1.insert(40);
    
    //set容器的特点:所有的元素插入时会被自动排序
    //set容器插入重复数据无用 每个元素只能出现一次
    printSet(s1);
    
    sets2(s1);  //拷贝构造
    printSet(s2);
    
    sets3;
    s3 = s2;  //等号赋值
    printSet(s3);
    
}
int main() {
    test01();
    return 0;
}

输出结果:

10 20 30 40 

10 20 30 40 

10 20 30 40 

set大小和交换

size();  //返回容器中元素个数

empty();  //判断容器是否为空

swap(st);  //交换两个集合容器

注意⚠️:set容器并没有resize()函数 假如我们用resize把原先的容器扩展变长 resize会以零来填充 而set容器是不允许插入重复的值 所以问题出现在了这里

#include 
using namespace std;
#include 

//set容器大小和交换

void printSet(const set&s){
    for(set::const_iterator it = s.begin();it != s.end();it++){
        cout << *it << " ";
    }
    cout <s1;
    //插入数据 只有insert方法
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    
    //打印容器
    printSet(s1);
    
    //判断是否为空
    if(s1.empty()){
        cout << "s1为空" << endl;
    }else{
        cout << "s1不为空" << endl;
        cout << "s1的元素个数为: " << s1.size() << endl;
    }
    
    sets2;
    s2.insert(9);
    s2.insert(99);
    s2.insert(999);
    
    cout << "交换前: " << endl;
    printSet(s1);
    printSet(s2);
    
    s1.swap(s2);
    cout << "交换后: " << endl;
    printSet(s1);
    printSet(s2);
}
int main() {
    test01();
    return 0;
}

输出结果:

10 20 30 40 

s1不为空

s1的元素个数为: 4

交换前: 

10 20 30 40 

9 99 999 

交换后: 

9 99 999 

10 20 30 40 

set插入和删除

insert(elem);  //在容器中插入元素elem

clear();  //清除所有元素

erase(pos);  //删除pos迭代器所指的元素 返回下个元素的迭代器

erase(beg, end);  //删除区间内的所有元素 返回下一个元素的迭代器

erase(elem); //删除容器中值为elem的元素

#include 
using namespace std;
#include 


void printSet(const set&s){
    for(set::const_iterator it = s.begin();it != s.end();it++){
        cout << *it << " ";
    }
    cout <s1;
    //插入数据 只有insert方法
    s1.insert(30);
    s1.insert(10);
    s1.insert(20);
    s1.insert(40);
    s1.insert(15);
    
    //遍历
    printSet(s1);
    
    //删除
    s1.erase(s1.begin()); //删除自动排序后的第一个元素10
    printSet(s1);
    
    s1.erase(30); //删除重载版本
    printSet(s1);
    
    //区间删除
    s1.erase(s1.begin(),s1.end());  //相当于清空了
    
    //清空
    s1.clear(); //和上一行代码效果一样
}
int main() {
    test01();
    return 0;
}

输出结果:

10 15 20 30 40 

15 20 30 40 

15 20 40 

set查找和统计

 find(key);  //查找key是否存在 存在则返回该键的迭代器 不存在则返回set.end();

 count(key);  //统计key的元素个数

#include 
using namespace std;
#include 


void printSet(const set&s){
    for(set::const_iterator it = s.begin();it != s.end();it++){
        cout << *it << " ";
    }
    cout <s1;
    //插入数据 只有insert方法
    s1.insert(30);
    s1.insert(10);
    s1.insert(20);
    s1.insert(40);
    s1.insert(30);
    
    //遍历
    printSet(s1);
    
    //通过迭代器去接收find的返回值
    set::iterator pos = s1.find(30);
    
    if(pos != s1.end()){
        cout << "找到元素" << *pos << endl;
    }else{
        cout << "未找到元素" << endl;
    }
    
    //统计元素30的个数
    unsigned long num1 = s1.count(30);
    cout << "30的个数为: " << num1 << endl;
    
    //统计元素300
    unsigned long num2 = s1.count(300);
    cout << "300的个数为: " << num2 << endl;
    
    //总结:对set而言 count统计的结果不是1就是0 因为set不允许出现重复数
}
int main() {
    test01();
    return 0;
}

输出结果:

10 20 30 40 

找到元素30

30的个数为: 1

300的个数为: 0

set和multiset区别

1.set不可以插入重复的数据 而multiset可以

2.set插入数据的同时会返回插入结果 表示插入成功(等下会详细讲到)

3.multiset不会检测数据 因此可以插入重复数据

 

#include 
using namespace std;
#include 


void printSet(const set&s){
    for(set::const_iterator it = s.begin();it != s.end();it++){
        cout << *it << " ";
    }
    cout <s;
    
    //插入这个数据的时候会返回一个对组
    //pair
    //第一个迭代器代表插入到哪里了 第二个bool表明是否插成功了
    pair::iterator, bool> ret = s.insert(10);
    
    //ret.second表明对组中的第二个数据bool
    if(ret.second){
        cout << "第一次插入成功" << endl;
    }else{
        cout << "第一次插入失败" << endl;
    }
    
    ret = s.insert(10); //第二次插入10
    if(ret.second){
        cout << "第二次插入成功" << endl;
    }else{
        cout << "第二次插入失败" << endl;
    }
}
void test02(){
    multisetms;
    
    //multiset只会返回一个代迭器 没有bool来判断是否插入成功
    //所以multiset是允许插入重复的数据的
    ms.insert(10);
    ms.insert(10);
    
    //遍历multiset
    for(multiset::iterator it = ms.begin();it != ms.end();it++){
        cout << *it << " ";
    }
    cout << endl;
}
int main() {
    test01();
    test02();
    return 0;
}

输出结果:

第一次插入成功

第二次插入失败

10 10 

pair对组创建

功能描述:成对出现的数据 利用对组可以返回两个数据

pair p (value1, value2);  //type是数据类型 value是对应的值

pair p = make_pair(value1, value2);

#include 
using namespace std;
#include 

void test01(){
    //第一种方式
    pairp1("张三",25);
    cout << "姓名:" << p1.first << "  年龄:" << p1.second << endl;
    
    //第二种方式
    pairp2 = make_pair("李四", 40);
    cout << "姓名:" << p2.first << "  年龄:" << p2.second << endl;
}
int main() {
    test01();
    return 0;
}

输出结果:

姓名:张三  年龄:25

姓名:李四  年龄:40

 set容器排序-内置数据类型

主要技术点:set容器默认排序从小到大 利用仿函数 可以改变排序规则

仿函数就是重载了()运算符

注意⚠️:已经insert完的数据是不能改变排序规则了 要想改变规则必须在插入前就通过仿函数改变排序规则

#include 
using namespace std;
#include 

class MyCompare{
public:
    //重载()运算符
    bool operator()(int v1, int v2){
        //降序
        return v1 > v2;
    }
};
void printSet1(set &s){
    for(set::iterator it = s.begin();it !=s.end();it++){
        cout << *it << " ";
    }
    cout << endl;
}
void printSet2(set &s){
    for(set::iterator it = s.begin();it !=s.end();it++){
        cout << *it << " ";
    }
    cout << endl;
}
void test01(){
    sets1;
    //插入的时候自动从小到大排序
    s1.insert(30);
    s1.insert(10);
    s1.insert(20);
    s1.insert(15);
    
    printSet1(s1);
    
    //指定排序规则从大到小
    //按照仿函数的排序规则
    sets2;
    
    s2.insert(30);
    s2.insert(10);
    s2.insert(20);
    s2.insert(15);
    
    printSet2(s2);
    
}
int main() {
    test01();
    return 0;
}

输出结果:

10 15 20 30 

30 20 15 10 

 set容器排序-自定义数据类型

#include 
using namespace std;
#include 

class Person{
public:
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
    string name;
    int age;
};

class comparePerson{
public:
    bool operator()(const Person &p1, const Person &p2){
        //降序
        return p1.age > p2.age;
    }
};
void printSet1(set &s){
    for(set::iterator it = s.begin();it !=s.end();it++){
        cout << "姓名:"<< it->name << " 年龄:" << it->age << endl;
    }
    cout << endl;
}
void test01(){
    //自定义的数据类型 都会指定排序规则
    //不然系统不知道按照什么排序
    
    sets;
    
    Person p1("张三",18);
    Person p2("李四",40);
    Person p3("王五",28);
    
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    
    printSet1(s);
}
int main() {
    test01();
    return 0;
}

输出结果:

姓名:李四 年龄:40

姓名:王五 年龄:28

姓名:张三 年龄:18

你可能感兴趣的:(c++)