C ++ STL - set and multiset


Note: The original is not easy, reproduced, please be sure to indicate the source and author, thanks for the support!

Note: content from a training course, may not be entirely correct!

A set and multiset

Characteristics are set and multiset of all elements will be sorted automatically according to the value of the element. set and multiset to red-black tree (a balanced binary tree) to the underlying mechanism. Find its efficiency is very good. container does not allow duplicate set of elements, multiset allows repeated elements present.

Constructor

set<T> st;              // 默认构造函数
multiset<T> mst;        // multiset默认构造函数
set(const set &st);     // 拷贝构造函数

Assignment

set &operator=(const set &st);  // 重载等号运算符
swap(st);                       // 交换两个集合容器中的元素

The size of the operation

size();     // 返回容器中元素的数目
empty();    // 判断容器是否为空

Insert and delete

insert(elem);       // 在容器中插入元素
clear();            // 清空所有元素
erase(pos);         // 删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end);    // 删除区间[beg, end)的所有元素
erase(elem);        // 删除容器中值为elem的元素

Find operation

find(key);              // 查找键key是否存在,若存在,返回该元素的迭代器;若不存在,则返回map.end()
lower_bound(keyElem);   // 返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem);   // 返回第一个key>keyElem元素的迭代器
equal_range(keyElem);   // 返回容器中key和keyElem相等的上下限的两个迭代器

Here is the application case set and multiset.

void printSet(set<int> &v)
{
    decltype(v.begin()) it;
    for (it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void printMultiset(multiset<int> &mst)
{
    decltype(mst.begin()) it;
    for (it = mst.begin(); it != mst.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void Test1()
{
    // 初始化
    set<int> s1;
    s1.insert(7);
    s1.insert(2);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);
    printSet(s1);

    // 赋值
    set<int> s2 = s1;
    printSet(s2);

    set<int> s3;
    s3.swap(s1);
    printSet(s1);
    printSet(s3);

    // 删除
    s3.erase(s3.begin());
    printSet(s3);
    s3.erase(7);
    printSet(s3);

    // multiset
    multiset<int> mst;
    mst.insert(7);
    mst.insert(6);
    mst.insert(9);
    mst.insert(1);
    mst.insert(6);
    cout << "mst = " << endl;
    decltype(mst.begin()) it;
    for (it = mst.begin(); it != mst.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    // 查找
    set<int> st;
    for (int i = 1; i <= 10; ++i)
    {
        st.insert(i * 10);
    }
    printSet(st);

    set<int>::iterator itlow, itup;
    // 第一个key >= 30的元素的迭代器
    itlow = st.lower_bound(30);
    // 第一个key > 60的元素的迭代器
    itup = st.upper_bound(60);
    cout << "*itlow = " << *itlow << endl;
    cout << "*itup = " << *itup << endl;
    st.erase(itlow, itup);
    printSet(st);

    // equal_range()
    multiset<int> s;
    s.insert(10);
    s.insert(20);
    s.insert(20);
    s.insert(20);
    s.insert(30);
    s.insert(40);
    printMultiset(s);

    pair<decltype(s.begin()), decltype(s.begin())> iteq;
    iteq = s.equal_range(20);
    cout << "*iteq.first = " << *iteq.first << endl;
    cout << "*iteq.second = " << *iteq.second << endl;
    s.erase(iteq.first, iteq.second);
    printMultiset(s);
}

Use functor change the default sort of container set
in the above case, we know that container set default is int data from small to large sort. So how do you let it set descending order? Consider the following example.

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

// 从大到小排序
void Test2()
{
    set<int, MyCompare> s1;
    s1.insert(7);
    s1.insert(2);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);
    decltype(s1.begin()) it;
    for (it = s1.begin(); it != s1.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
}

which set the container on how to place objects
if you just write the words is not enough!

class Person
{
public:
    Person(int id, int age) : id(id), age(age) {}
public:
    int id;
    int age;
};
    
void Test3()
{
    // 会报错!因为set内部是需要排序的,当你往set里放置对象时,
    // set是不知道如何对对象进行排序的。这与基础数据类型不同
    set<Person> sp;
    Person p1(1000, 20);
    Person p2(1001, 21);
    Person p3(1002, 22);
    sp.insert(p1);
    sp.insert(p2);
    sp.insert(p3);
}

Then how to solve this problem? Use functor! As follows.

class cmp
{
public:
    bool operator() (const Person &p1, const Person &p2)
    {
        // 根据ID从小到大排序
        return p1.id < p2.id;
    }
};

void Test3()
{
    // 会报错!因为set内部是需要排序的,当你往set里放置对象时,
    // set是不知道如何对对象进行排序的。这与基础数据类型不同
    // set<Person> sp;

    // 正确的写法
    set<Person, cmp> sp;
    Person p1(1000, 23);
    Person p2(1001, 26);
    Person p3(1002, 22);
    sp.insert(p1);
    sp.insert(p2);
    sp.insert(p3);

    decltype(sp.begin()) it;
    for (it = sp.begin(); it != sp.end(); ++it)
    {
        cout << "id = " << it->id << " " << "age = " << it->age << endl;
    }

    // 务必注意:因为仿函数cmp里只对Person的ID进行比较
    // 所以在下面的案例中,在sp中查找p4,结果理应是p4不在
    // sp中的。但是,因为cmp直对Person的ID进行比较,所以
    // 下面案例的实际输出是p4在sp中!,因为p4的ID和p3的ID
    // 相同。所以,it返回的实际上是p3的迭代器!!!!!!
    Person p4(1002, 29);
    it = sp.find(p4);
    if (it != sp.end())
    {
        cout << "p4在sp中!" << endl;
        cout << "id = " << it->id << " " << "age = " << it->age << endl;
    }
    else
    {
        cout << "p4不在sp中!" << endl;
    }
}

Find important to note that the above cases precautions!

Two pairs of group pair

For group (pair) a pair of values ​​into one value, the data type may have different values, two values ​​can be a function of two public first pair and second access, respectively.

Creation of a group

// 方法一
pair<string, int> p1(string("name"), 20);
cout << p1.first << endl;
cout << p1.second << endl;

// 方法二
pair<string, int> p2 = make_pair("name", 20);
cout << p2.first << endl;
cout << p2.second << endl;

// 对组的赋值
pair<string, int> p3 = p2;
cout << p3.first << endl;
cout << p3.second << endl;

Guess you like

Origin www.cnblogs.com/laizhenghong2012/p/11785869.html