0
点赞
收藏
分享

微信扫一扫

C++容器 - set & map

伽马星系 2022-01-16 阅读 163

set / multiset 容器

set 容器

基本概念

简介:所有元素都会在插入时自动被排序
本质:set / multiset 属于关联式容器,底层结构是用 二叉树 实现

set 和 multiset 的区别

  • set 不允许容器中有重复的元素,multiset 允许容器可以
  • set 插入数据的同时会返回插入结果,表示插入是否成功
  • multiset 不会检测数据,因此可以插入重复数据

set 构造和赋值

构造

  • set<T> st; // 默认构造函数;
  • set(const set& st); // 拷贝构造函数
    赋值
  • ` set& operator=(const set &st); // 重载等号操作符

案例

void prt(set<int>& st)
{
    for (auto i : st)
        cout << i << " ";
    cout << endl;
}

void test1()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(30);
    s1.insert(10);
    prt(s1);	// 输出 10 20 30

	set<int> s2;
    s2.insert(10);
    s2.insert(20);
    s2.insert(30);
    prt(s2);	// 同样输出 10 20 30
}

set 大小和交换

  • size();
  • empty();
  • swap(st);

set 插入和删除

  • insert(elem);
  • clear();
  • erase(pos);
  • erase(beg, end);
  • erase(elem); // 删除容器中值为 elem 的元素

set 查找和统计

  • find(key); // 若 key 存在,返回该键元素的迭代器,若不存在返回set.end()
  • count(key); // 统计 key 的元素个数,因为set不存在重复的元素,所以始终返回1

pair 对组创建

set 的 insert 操作的实现是 pair<iterator, bool>,multiset 的 insert 操作的实现是 < iterator >

  • pair<type, type> pr(value1, value2);
  • pair<type, type> pr = make_pair(value1, value2);

案例

void test1()
{
    pair<string, int> p("Tom", 23);
    cout << p.first << " " << p.second << endl;
    
    pair<string, int> p2 = make_pair("Bob", 33);
    cout << p2.first << " " << p2.second << endl;
}

set 容器排序

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

案例1 - 内置数据类型

class Cmp {	// 指定仿函数,进行降序排序
public:
    bool operator()(int a, int b) const
    {
        return a > b;
    }
};

void sprt(set<int, Cmp>& st)
{
    for (auto i : st)
        cout << i << " ";
    cout << endl;
}

void test2()
{
    // 指定排序规则为从大到小
    set<int, Cmp> s1;
    s1.insert(11);
    s1.insert(18);
    s1.insert(12);
    s1.insert(15);
    s1.insert(14);
    s1.insert(11);
    sprt(s1);	// 输出结果 18 15 14 12 11
}

案例2 - 自定义数据类型

对于自定义的数据类型必须要 指定排序规则

class Person {	// 自定义数据类型
public:
    Person(string name, int age)
    {
        this->name_ = name;
        this->age_ = age;
    }

    string name_;
    int age_;
};

class CpmPers {	// 自定义仿函数,进行降序进行排序
public:
    bool operator()(const Person& a, const Person& b)
    {
        // 按照年龄降序
        return a.age_ > b.age_;
    }
};

void test3()
{
    set<Person, CpmPers> s1;
    Person p1("Lucy", 22);
    Person p2("Mary", 24);
    Person p3("Jack", 23);
    Person p4("Tomi", 25);
	// 默认插入的排序顺序是按照字符串,所以会出现错误
    s1.insert(p1);
    s1.insert(p2);
    s1.insert(p3);
    s1.insert(p4);

    for (set<Person, CpmPers>::iterator it = s1.begin();
    	 it != s1.end(); ++it) {
        cout << "Name: " << it->name_ 
        	 << ", Age: " << it->age_ << endl;
    }
    /* 输出结果:
	    Name: Tomi, Age: 25
		Name: Mary, Age: 24
		Name: Jack, Age: 23
		Name: Lucy, Age: 22
	*/
}

map / multimap 容器

map

概念

  • map 中所有元素都是 pair
  • pair中第一个元素为 key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序
  • map / multimap 属于 关联容器 ,底层结构是用二叉树实现。
  • 可以根据 key 值快速找到 value 值

map 和 multimap 的区别

  • map 中不允许容器中有重复 key 值元素
  • multimap 允许容器中有重复 key 值元素

map 构造 和 赋值

  • map<T1, T2> mp; // 默认构造函数
  • map<const map& mp); // 拷贝构造函数
  • map& operator=(const map& mp); // 重载等号赋值操作符

map 大小 和 交换

  • size(); // 返回容器中元素的数目
  • empty(); // 判断容器是否为空
  • swap(); // 交换两个集合容器

map 插入 和 删除

  • insert(elem); // 在容器中插入元素
  • clear();
  • erase(pos); // 删除 pos 位置上所指的元素,返回下一个迭代器
  • erase(beg, end);
  • erase(key); // 删除容器中值为 key 的元素

map 查找 和 统计

  • find(key);
  • count(key); // 统计 key 的元素个数,map中没有重复的 key,multimap 的count 可能大于 1

map 容器排序

map 的默认排序规则是 升序
和 set 一样,可以利用仿函数改变排序的规则为 降序

案例

class CmpMap {
public:
    bool operator()(int a, int b)
    {
        return a > b;
    }
};

void PrtMap(map<int, int, CmpMap>& m)
{
    for (map<int, int, CmpMap>::iterator it = m.begin(); it != m.end(); ++it) {
        cout << "key: " << it->first << " Second: " << it->second << endl;
    }
    cout << endl;
}

void test06()
{
    map<int, int, CmpMap> m;
    m.insert(pair<int, int>(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(4, 40));
    m.insert(make_pair(5, 50));
    PrtMap(m);
}
举报

相关推荐

0 条评论