【C++STL容器篇之set】

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

set

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

本质setmultiset 属于关联式容器,底层结构是用二叉树实现的

set & multiset的区别:

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

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

 set 构造器与赋值

【函数原型】:

- set<T> st; //默认构造函数

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

- set operator=(const set &st); //重载等号操作符
复制代码

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
    if (st.empty())
    {
        cout << "set is empty ." << endl;
    }
    else
    {
        for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size : " << st.size() << endl;
    }
}
void test01()
{
    set<int> st;

    st.insert(50);
    st.insert(30);
    st.insert(10);
    st.insert(20);
    st.insert(40);
    printSet(st);

    // 拷贝构造
    set<int> st2(st);
    printSet(st2);

    // 赋值
    set<int> st3;
    st3 = st2;
    printSet(st3);
}
int main()
{
    test01();
    return 0;
}
复制代码

小结

  • set 容器插入元素时用insert

  • set容器插入元素时会自动排序

set 大小和交换(demo2.cpp)

【函数原型】:

- size(); //返回容器中元素的数目

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

- swap(); // 交换两个集合容器
复制代码

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
    if (st.empty())
    {
        cout << "set is empty ." << endl;
    }
    else
    {
        for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size : " << st.size() << endl;
    }
}
void test01()
{
    set<int> st;

    st.insert(50);
    st.insert(30);
    st.insert(10);
    st.insert(20);
    st.insert(40);

    set<int> st2;
    st2.insert(100);
    st2.insert(300);
    st2.insert(400);
    st2.insert(200);
    st2.insert(500);
    cout << "===== before swap ===== " << endl;
    cout << "set1 : ";
    printSet(st);
    cout << "set2 : ";
    printSet(st2);

    st.swap(st2);
    cout << "===== after swap ===== " << endl;
    cout << "set1 : ";
    printSet(st);
    cout << "set2 : ";
    printSet(st2);
}
int main()
{
    test01();
    return 0;
}
复制代码

set 插入元素和删除元素

【函数原型】:

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

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

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

- erase(begin,end); // 删除[begin,end]区间中的元素,返回下一个元素的迭代器

- erase(elem); // 删除容器中值为elem的元素
复制代码

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
    if (st.empty())
    {
        cout << "set is empty ." << endl;
    }
    else
    {
        for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size : " << st.size() << endl;
    }
}
void test01()
{
    set<int> st;

    // 插入元素
    st.insert(50);
    st.insert(30);
    st.insert(10);
    st.insert(20);
    st.insert(40);
    printSet(st);

    // 删除元素
    st.erase(st.begin());
    printSet(st);

    // 清空元素
    st.clear();
    printSet(st);
}
int main()
{
    test01();
    return 0;
}
复制代码

set 查找和统计

【函数原型】:

- find(key); // 查找key是否存在,若存在,则返回key对应的迭代器,若不存在,返回set.end();

- count(key); // 统计key的元素个数
复制代码

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
    if (st.empty())
    {
        cout << "set is empty ." << endl;
    }
    else
    {
        for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size : " << st.size() << endl;
    }
}
void test01()
{
    set<int> st;

    // 插入元素
    st.insert(50);
    st.insert(30);
    st.insert(10);
    st.insert(20);
    st.insert(40);
    printSet(st);

    // 查找元素
    set<int>::iterator pos = st.find(30);
    if (pos != st.end())
    {

        cout << "find " << *pos << endl;
    }
    else
    {
        cout << "not found . " << endl;
    }

    // 统计元素个数
    int num = st.count(10);
    cout << "num = " << num << endl;
}
int main()
{
    test01();
    return 0;
}
复制代码

set 与 multiset区别

  • set 不可以插入重复数据,而 multiset 可以

  • set 插入数据的同时会返回插入结果,表示插入是否成功

  • multiset 不会检测数据,可以插入重复数据

【demo】:

#include <iostream>
#include <set>

using namespace std;

// set和multiset的区别
void test01()
{
    set<int> s;
    pair<set<int>::iterator, bool> ret = s.insert(10);
    if (ret.second)
    {
        cout << "set 第一次插入成功" << endl;
    }
    else
    {
        cout << "set 第一次插入失败" << endl;
    }

    ret = s.insert(10);
    if (ret.second)
    {
        cout << "set 第二次插入成功" << endl;
    }
    else
    {
        cout << "set 第二次插入失败" << endl;
    }

    multiset<int> ms;
    ms.insert(10);
    ms.insert(10);
    cout << "multiset:";
    for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}
int main()
{
    test01();
    return 0;
}
复制代码

pair对组创建

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

【函数原型】:

- pair(type,type) p (value1,value2);

- pair(type,type) p = make_pair(value1,value2);
复制代码

【demo】:

#include <iostream>
#include <string>

using namespace std;

// 对组创建
void test01()
{
    pair<string, int> p(string("张三"), 20);
    cout << "姓名:" << p.first << ",年龄:" << p.second << endl;

    pair<string, int> p2 = make_pair("李四", 22);
    cout << "姓名:" << p2.first << ",年龄:" << p2.second << endl;
}
int main()
{
    test01();
    return 0;
}
复制代码

set 容器排序

set 容器默认排序规则为从小到大,利用仿函数,可以改变排序规则
复制代码

【demo】:

#include <iostream>
#include <set>

using namespace std;

class MyCompare
{
public:
    bool operator()(int v1, int v2)
    {
        return v1 > v2;
    }
};

void test01()
{
    set<int> s1;
    s1.insert(19);
    s1.insert(5);
    s1.insert(10);
    s1.insert(3);

    cout << "默认从小到大排序:";
    for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    set<int, MyCompare> s2;
    s2.insert(19);
    s2.insert(5);
    s2.insert(10);
    s2.insert(3);
    cout << "指定从大大小排序:";

    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}
int main()
{
    test01();
    return 0;
}
复制代码

set 存放自定义数据类型

对于自定义数据类型,set必须指定排序规则才可以插入数据
复制代码

【demo】:

#include <iostream>
#include <string>
#include <set>

using namespace std;

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

public:
    string m_name;
    int m_age;
};

class PersonCompare
{
public:
    bool operator()(const Person &p1, const Person &p2)
    {
        // 按照年龄降序排列
        return p1.m_age > p2.m_age;
    }
};
void test01()
{
    Person p1("张三", 20);
    Person p2("李四", 23);
    Person p3("王五", 22);
    Person p4("赵六", 21);

    set<Person, PersonCompare> s;
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);

    for (set<Person, PersonCompare>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << it->m_name << "," << it->m_age << endl;
    }
}
int main()
{
    test01();
    return 0;
}
复制代码

猜你喜欢

转载自juejin.im/post/7019691349318320165