• C++ STL进阶与补充(set/multiset容器)


    集合容器:所有元素在插入时自动排序,set/multiset属于关联式容器,底层结构由二叉树实现。

    Set和multiset的区别:set不允许容器中有重复的元素;multiset允许容器中有重复的元素。

    Set在插入数据时会返回插入结果,表示插入是否成功。Multiset则不会检测。

    例:

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. void printSet(const set<int>& s)
    5. {
    6. for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. set<int> s1;
    15. //插入,只能insert方式
    16. pair<set<int>::iterator, bool> ret = s1.insert(10); //set是一个对组的数据类型
    17. if (ret.second)
    18. {
    19. cout << "set第1次插入成功!" << endl;
    20. }
    21. else
    22. {
    23. cout << "set第1次插入失败!" << endl;
    24. }
    25. ret=s1.insert(10);
    26. if (ret.second)
    27. {
    28. cout << "set第2次插入成功!" << endl;
    29. }
    30. else
    31. {
    32. cout << "set第2次插入失败!" << endl;
    33. }
    34. multiset<int> s2;
    35. s2.insert(10);
    36. s2.insert(10);
    37. s2.insert(10);
    38. for (multiset<int>::iterator it = s2.begin(); it != s2.end(); it++)
    39. {
    40. //multiset不会检测,直接打印即可
    41. cout << *it << " ";
    42. }
    43. cout << endl;
    44. }
    45. int main()
    46. {
    47. test01();
    48. }

    1、set构造和赋值

    Set<T> st;

    默认构造

    Set(const set& st)

    拷贝构造

    =

    等号运算符重载,等号赋值

    Set在插入数据时,只有Insert的方式。

    Set容器的特点:1、所有元素插入时自动排序;2、不允许插入重复的值

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. void printSet(const set<int>& s)
    5. {
    6. for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. set<int> s1;
    15. s1.insert(10);
    16. s1.insert(20);
    17. s1.insert(30);
    18. s1.insert(20); //不报错,但是并不会插入
    19. s1.insert(40);
    20. printSet(s1);
    21. }
    22. int main()
    23. {
    24. test01();
    25. }

    2、set大小和互换

    Size()

    返回容器中元素个数。

    Empty()

    判断容器是否为空。

    Swap(st)

    交换两个集合的容器。

    Set容易不允许有修改大小的操作,例如resize。

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. void printSet(const set<int>& s)
    5. {
    6. for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. set<int> s1;
    15. s1.insert(10);
    16. s1.insert(20);
    17. s1.insert(30);
    18. printSet(s1);
    19. if (s1.empty())
    20. {
    21. cout << "s1为空。" << endl;
    22. }
    23. else
    24. {
    25. cout << "s1不为空。" << endl;
    26. cout << "s1的大小为:" << s1.size() << endl;
    27. }
    28. }
    29. int main()
    30. {
    31. test01();
    32. }

    3、set插入和删除

    Insert(elem)

    在容器中插入元素

    Clear()

    清空所有元素

    Erase(pos)

    删除pos迭代器所指的元素,返回下一个元素的地址的迭代器

    Erase(beg,end)

    删除区间[beg,end]的所有元素,返回下一个元素的迭代器

    Erase(elem)

    删除容器中值为elem的元素

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. void printSet(const set<int>& s)
    5. {
    6. for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. set<int> s1;
    15. //插入,只能insert方式
    16. s1.insert(10);
    17. s1.insert(20);
    18. s1.insert(30);
    19. s1.insert(40);
    20. printSet(s1); //10 20 30
    21. //删除
    22. s1.erase(s1.begin());
    23. printSet(s1); //20 30 40
    24. //删除的重载版本
    25. s1.erase(30);
    26. printSet(s1); //20 40
    27. }
    28. int main()
    29. {
    30. test01();
    31. }

    4、set查找和统计

    Find(key)

    查找key元素是否存在,若存在则返回键的元素的迭代器,否则返回sed.end()

    Count(key)

    统计key的元素个数,通常来说只返回0和1,multiset则可能大于1.

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. void printSet(const set<int>& s)
    5. {
    6. for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. set<int> s1;
    15. //插入,只能insert方式
    16. s1.insert(10);
    17. s1.insert(20);
    18. s1.insert(30);
    19. s1.insert(40);
    20. set<int>::iterator pos = s1.find(30);
    21. if (pos != s1.end())
    22. {
    23. cout << "找到元素:" << *pos << endl;
    24. }
    25. else
    26. {
    27. cout << "未找到!" << endl;
    28. }
    29. }
    30. int main()
    31. {
    32. test01();
    33. }

    5、pair对组的创建

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

    Pair<type, type> p(value, value);

    默认构造

    Pair<type, type> p=make_pair(value, value);

    Make_pair方式

    1. #include<iostream>
    2. #include"string"
    3. using namespace std;
    4. void test01()
    5. {
    6. pair<string, int> p("Tom", 20);
    7. cout << "Name: " << p.first << " " << "Age: " << p.second << endl;
    8. //第二种方式
    9. pair<string, int> p2 = make_pair("Jerry", 30);
    10. cout << "Name: " << p2.first << " " << "Age: " << p2.second << endl;
    11. }
    12. int main()
    13. {
    14. test01();
    15. }

    6、set内置类型指定排序规则

    Set容器默认排序规则为从小到大,那么如何改变其排序规则呢?主要利用仿函数。

    可以分为两种情况的排序:首先是内置数据类型的排序,如int,char等,其次是自定义数据类型的排序。

    case 1:

    1. #include<iostream>
    2. #include<set>
    3. using namespace std;
    4. class myCompare
    5. {
    6. public:
    7. bool operator()(int v1, int v2) const
    8. {
    9. return v1 > v2;//降序排列
    10. }
    11. };
    12. void test01()
    13. {
    14. set<int> s1;
    15. //需要在插入数据之前,告诉set排序方式是什么
    16. s1.insert(30);
    17. s1.insert(10);
    18. s1.insert(50);
    19. s1.insert(40);
    20. for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
    21. {
    22. cout << *it << " ";
    23. }
    24. cout << endl;
    25. set<int,myCompare> s2; //需要在插入数据之前,告诉set排序方式是什么
    26. s2.insert(30);
    27. s2.insert(10);
    28. s2.insert(50);
    29. s2.insert(40);
    30. for (set<int,myCompare>::iterator it = s2.begin(); it != s2.end(); it++)
    31. {
    32. cout << *it << " ";
    33. }
    34. cout << endl;
    35. }
    36. int main()
    37. {
    38. test01();
    39. }

    case 2:

    1. #include<iostream>
    2. #include<set>
    3. #include"string"
    4. using namespace std;
    5. class Person
    6. {
    7. public:
    8. Person(string name, int age)
    9. {
    10. this->m_name = name;
    11. this->m_age = age;
    12. }
    13. string m_name;
    14. int m_age;
    15. };
    16. class myCompare
    17. {
    18. public:
    19. bool operator()(const Person& p1, const Person& p2) const
    20. {
    21. return p1.m_age >p2.m_age ;//降序排列
    22. }
    23. };
    24. void test01()
    25. {
    26. set<Person,myCompare> s;
    27. Person p1("WXQ", 28);
    28. Person p2("ZWY", 22);
    29. Person p3("WAL", 30);
    30. Person p4("ZYM", 27);
    31. //需要在插入数据之前,告诉set排序方式是什么,否则会报错
    32. s.insert(p1);
    33. s.insert(p2);
    34. s.insert(p3);
    35. s.insert(p4);
    36. for (set<Person,myCompare>::iterator it = s.begin(); it != s.end(); it++)
    37. {
    38. cout << "name: " << (*it).m_name<<" "<<"age: "<<(*it).m_age<<endl;
    39. }
    40. }
    41. int main()
    42. {
    43. test01();
    44. }
  • 相关阅读:
    50个常用的Java代码示例
    IntelliJ IDEA一站式配置【全】(提高开发效率)
    基于Spark的大规模日志分析
    成为会带团队的技术人 技术债务:如何带领团队从困境中突围而出?
    java8流处理器list转map的对比
    MySQL数据类型介绍及使用场景
    Non-zero exit code pycharm
    如何保护数据安全?企业该从部署SSL证书开始
    Pro_07丨波动率因子3.0与斜率因子
    (附源码)ssm微课堂知识考核系统 毕业设计 141147
  • 原文地址:https://blog.csdn.net/Lao_tan/article/details/125468582