C++学习 --- STL常用容器之set容器

7、set/multiset 容器

7.1、set基本概念

简介:

  • 所有所有元素都会在插入时自动被排序

本质:

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

set和multiset区别:

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

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

7.2、set构造和赋值

功能描述:创建set容器以及赋值

#include <iostream>
#include <set>
using namespace std;
​
/*
set<T> st;//默认构造函数;
set(const set & st); //拷贝构造函数
set & operator=(const set &st);//重载等号操作符
*///set容器的构造和赋值
void printSet(set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end();it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
void test01() {
    set<int> s1;
    
    //插入数据只有insert方式
    s1.insert(10);
    s1.insert(40);
    s1.insert(30);
    s1.insert(20);
    s1.insert(30);
        
    //set容器特点:
    //所有元素插入时自动被排序
    //set容器不允许插入重复的值
    //遍历容器
    printSet(s1);
​
    //拷贝构造
    set<int> s2(s1);
    printSet(s2);
​
    //赋值
    set<int> s3;
    s3 = s2;
    printSet(s3);
}
​
​
int main() {
    test01();
​
    system("pause");
    return 0;
}
7.3、set大小和交换

功能描述:

  • 统计set容器大小以及 交换set容器

#include <iostream>
#include <set>
using namespace std;
​
/*
size();    //返回容器中元素的数目
empty();   //判断容器是否为空
swap(st);  //交换连个集合容器
没有resize():set容器不允许有重复的数,resize 默认填充值都是0,所以没有
*///set容器 大小和交换
void printSet(set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end();it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
//大小
void test01() {
    set<int> s1;
    
    //插入数据
    s1.insert(10);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
​
    //打印容器
    printSet(s1);
    if (s1.empty()) {
        cout << "s1 为空" << endl;        
    }
    else {
        cout << "s1不为空" << endl;        
    }
    cout << "s1的大小为:" << s1.size() << endl; 
}
​
//交换
void test02() {
    set<int> s1;
    //插入数据
    s1.insert(10);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
​
    set<int> s2;
    //插入数据
    s2.insert(100);
    s2.insert(300);
    s2.insert(400);
    s2.insert(200);
​
    cout << "交换前:" << endl;
    printSet(s1);
    printSet(s2);
​
    s1.swap(s2);
    cout << "交换后:" << endl;
    printSet(s1);
    printSet(s2);
​
}
​
int main() {
    //test01();
    test02();
    system("pause");
    return 0;
}
7.4、set插入和删除

#include <iostream>
#include <set>
using namespace std;
​
/*
insert(elem);  //在容器中插入元素
clear();       //清除所有元素
erase(pos);    //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(bfg,end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem);   //删除容器中值为elem的元素 
*///set容器 插入和删除
void printSet(set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end();it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
void test01() {
    set<int> s1;
    
    //插入数据
    s1.insert(30);
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    //10 20 30 40
    printSet(s1);
​
    //删除 传入迭代器
    s1.erase(s1.begin());
    //20 30 40
    printSet(s1);
​
    //删除重载版本 传入元素
    s1.erase(30);
    printSet(s1);
​
    //清空  提供区间的方式
    //s1.erase(s1.begin(),s1.end());
    s1.clear();
    printSet(s1);
}
​
​
int main() {
    test01();
​
    system("pause");
    return 0;
}
7.5、set查找和统计

#include <iostream>
#include <set>
using namespace std;
​
/*
find(key); // 查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key); //统计key的元素个数 (对于set而言,是0和1)
*///set容器 查找和统计
void printSet(set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end();it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
void test01() {
    set<int> s1;
    
    //插入数据
    s1.insert(30);
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    //10 20 30 40
    printSet(s1);
​
    //查找
    set<int>::iterator pos = s1.find(30);
    if (pos != s1.end()) {
        cout << "找到元素" << *pos << endl;
    }
    else {
        cout << "未找到元素" << endl;
    }
}
​
//统计
void test02() {
    set<int> s1;
​
    //插入数据
    s1.insert(30);
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(20);
    //10 20 30 40
    printSet(s1);
​
    //统计30的个数
    int num = s1.count(20);
    //对set而言,统计的结果 要么是0 要么是1
    cout << "num = " << num << endl;
}
​
int main() {
    test01();
    test02();
​
    system("pause");
    return 0;
}
7.6、set和multiset区别

#include <iostream>
#include <set>
using namespace std;
​
//set容器 和multiset 容器 区别
void printSet(set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end();it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
void test01() {
    set<int> s1;    
    
    //插入数据
    //using _Pairib = pair<iterator, bool>;
    //set.insert有两个返回值,一个迭代器,一个bool ,主要关注bool
    pair<set<int>::iterator,bool> ret = s1.insert(30);
    if (ret.second) {
        cout << "第一次插入成功" << endl;
    }
    else {
        cout << "第一次插入失败" << endl;
    }
​
    ret = s1.insert(30);
    if (ret.second) {
        cout << "第二次插入成功" << endl;
    }
    else {
        cout << "第二次插入失败" << endl;
    }
    //只有第一次插入成功
    printSet(s1);
​
    multiset<int> ms;
    //允许插入重复的值
    //multiset.insert有一个返回值,迭代器
    ms.insert(100);
    ms.insert(100);
    for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
​
int main() {
    test01();
​
    system("pause");
    return 0;
}
7.7、pair对组创建

功能描述:

成对出现的数据,利用对组可以返回两个数据

#include <iostream>
#include <string>
using namespace std;
​
/*
pair<type,type> p(value1,value2);
pair<type,type> p = make_pair(value1,value2);
*/
//对组的创建
void test01() {
    //第一种方式
    pair<string,int> p("Tom",20);
    cout << "姓名:" << p.first << " 年龄:" << p.second << endl;
    //第二种方式
    pair<string, int>p2 = make_pair("Jerry",30);
    cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}
​
int main() {
    test01();
​
    system("pause");
    return 0;
}
7.2、set容器排序
  • set容器默认排序规则为从小到大

  • 利用仿函数可以改变排序规则。

    set存放在内置数据类型

    #include <iostream>
    #include <set>
    using na数据类型mespace std;
    ​
    //set容器的排序 ,set存放在内置数据类型 
    //仿函数,本质是一个类型
    class MyCompare {
    public:
        //第一个()重载符号,第二个()参数列表
        bool operator()(int v1,int v2) {
            return v1 > v2;
        }
    };
    void test01() {
        set<int> s1;
        s1.insert(10);
        s1.insert(40);
        s1.insert(20);
        s1.insert(30);
    ​
        for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
            cout << *it << " ";
        }
        cout << endl;
    ​
        //改变排序规则为从大到小,需要在insert前改变
        //利用仿函数指定
        set<int,MyCompare> s2;
        s2.insert(10);
        s2.insert(40);
        s2.insert(20);
        s2.insert(30);
        //与要遍历的容器一致 set<int, MyCompare>
        for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
            cout << *it << " ";
        }
        cout << endl;
    }
    ​
    int main() {
        test01();
    ​
        system("pause");
        return 0;
    }

set存放自定义数据类型

#include <iostream>
#include <string>
#include <set>
using namespace std;
​
//set容器的排序,存放自定义数据类型
class Person {
public:
    Person(string name, int age) {
        this->m_Name = name;
        this->m_Age = age;
    }
    string m_Name;
    int m_Age;
};
​
//仿函数,本质是类
class comparePerson {
public:
    bool operator()(const Person &p1, const Person &p2) {
        //按照年龄 降序
        return p1.m_Age > p2.m_Age;
    }
};
​
void test01() {
    set<Person, comparePerson> s;
    //创建Person 对象
    Person p1("刘备", 24);
    Person p2("关羽", 28);
    Person p3("张飞", 25);
    Person p4("赵云", 21);
    //默认排序规则是从小到大,但自定义数据类型,编译器不知按照什么排序
    //通常自定义数据类型都会指定排序规则 set<Person, comparePerson>
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);
​
    for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++) {
        cout << (*it).m_Name << ":" << it->m_Age  << endl;
    }
}
​
int main() {
    test01();
​
    system("pause");
    return 0;
}

 

 

posted @ 2021-10-15 22:57  yiwenzhang  阅读(169)  评论(0编辑  收藏  举报