• 【C++】常用集合算法


    目录

    set_intersection

    set_union

    set_difference


    常用集合算法简介

    • set_intersection        求两个容器的交集
    • set_union                  求两个容器的并集
    • set_difference           求两个容器的差集

    set_intersection

    功能;

    • 求两个相同集合(必须是有序序列)的交集

    函数原型

    set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    beg1 —— 容器 1 开始迭代器

    end1 —— 容器 1 结束迭代器

    beg2 —— 容器 2 开始迭代器

    end2 —— 容器 2 结束迭代器

    dest  —— 目标容器开始迭代器

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. class Person {
    7. public:
    8. Person(string name, int age) :m_Name(name), m_Age(age) {}
    9. Person() {}
    10. string m_Name;
    11. int m_Age;
    12. };
    13. ostream& operator<<(ostream& cout, const Person& p) {
    14. cout << p.m_Name << " " << p.m_Age << endl;
    15. return cout;
    16. }
    17. template<typename T>
    18. void PrintVector(const T& x) {
    19. cout << x << " ";
    20. }
    21. // 内置数据类型交集
    22. void test01() {
    23. vector<int>v1; // 有序
    24. v1.push_back(3);
    25. v1.push_back(4);
    26. v1.push_back(5);
    27. v1.push_back(6);
    28. vector<int>v2; // 有序
    29. v2.push_back(4);
    30. v2.push_back(5);
    31. v2.push_back(6);
    32. vector<int>v_target; // 目标容器
    33. // 计算大小目标容器需要的合适大小
    34. size_t v_size = (v1.size() > v2.size()) ? v2.size() : v1.size();
    35. // 或者用 min 算法
    36. v_size = min(v1.size(), v2.size());
    37. // 需要给目标容器开辟内存 v_size
    38. v_target.resize(v_size); // 这个空间可能大了,默认值为 0
    39. // 求集合交集到目标容器,返回的是最后一个交集的迭代器
    40. vector<int>::iterator EndIt = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target.begin());
    41. // 遍历的时候可以不用遍历到容器末尾,只需要遍历到交集的最后一个元素即可
    42. for_each(v_target.begin(), EndIt, PrintVector<int>); // 遍历
    43. cout << endl;
    44. }
    45. class Person_sort {
    46. public:
    47. bool operator()(const Person& p1, const Person& p2) {
    48. return (p1.m_Age < p2.m_Age);
    49. }
    50. };
    51. // 自定义数据类型交集
    52. void test02() {
    53. vectorv1; // 有序
    54. vectorv2; // 有序
    55. Person p1("A", 19);
    56. Person p2("B", 18);
    57. Person p3("C", 20);
    58. Person p4("D", 21);
    59. v1.push_back(p1);
    60. v1.push_back(p2);
    61. v1.push_back(p3);
    62. v2.push_back(p1);
    63. v2.push_back(p2);
    64. v2.push_back(p3);
    65. v2.push_back(p4);
    66. sort(v1.begin(), v1.end(), Person_sort());
    67. sort(v2.begin(), v2.end(), Person_sort());
    68. vectorv_target;
    69. // 计算大小目标容器需要的合适大小
    70. size_t v_size = (v1.size() > v2.size()) ? v2.size() : v1.size();
    71. v_size = min(v1.size(), v2.size()); // min 算法
    72. // 需要给目标容器开辟内存 v_size
    73. v_target.resize(v_size);
    74. // 放上排序规则仿函数,返回最后一个交集的迭代器
    75. vector::iterator EndIt = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target.begin(), Person_sort());
    76. for_each(v_target.begin(), EndIt, PrintVector); // 遍历
    77. cout << endl;
    78. }
    79. int main() {
    80. test01();
    81. test02();
    82. system("pause");
    83. return 0;
    84. }

    运行结果:

    • 两个容器必须是有序序列
    • 目标容器取两个容器中的最小值
    • set_intersection 返回值是交集最后一个元素的位置

    set_union

    功能

    • 求两个集合(有序序列)的并集

    函数原型

    set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    beg1 ——  容器 1 开始迭代器

    end1 ——  容器 1  结束迭代器

    beg2 —— 容器 2 开始迭代器

    end2 —— 容器 2 结束迭代器

    dest  —— 目标容器开始迭代器

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. class Person {
    7. public:
    8. Person(string name, int age) :m_Name(name), m_Age(age) {}
    9. Person() {}
    10. string m_Name;
    11. int m_Age;
    12. };
    13. // 重载 <<
    14. ostream& operator<<(ostream& cout, const Person& p) {
    15. cout << p.m_Name << " " << p.m_Age << endl;
    16. return cout;
    17. }
    18. // 输出模板函数
    19. template<typename T>
    20. void PrintVector(const T& x) {
    21. cout << x << " ";
    22. }
    23. // 内置数据类型并集
    24. void test01() {
    25. vector<int>v1; // 有序
    26. vector<int>v2; // 有序
    27. v1.push_back(3);
    28. v1.push_back(4);
    29. v1.push_back(5);
    30. v1.push_back(6);
    31. v2.push_back(5);
    32. v2.push_back(6);
    33. v2.push_back(7);
    34. vector<int>v_target;
    35. v_target.resize(v1.size() + v2.size()); // 并集容量要取两个容器的和
    36. // 返回并集最后一个元素的迭代器
    37. vector<int>::iterator EndIt = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target.begin());
    38. for_each(v_target.begin(), EndIt, PrintVector<int>);
    39. cout << endl;
    40. }
    41. // 排序仿函数
    42. class Person_sort {
    43. public:
    44. bool operator()(const Person& p1, const Person& p2) {
    45. return (p1.m_Age < p2.m_Age);
    46. }
    47. };
    48. // 自定义数据类并集
    49. void test02() {
    50. vectorv1; // 有序
    51. vectorv2; // 有序
    52. Person p1("A", 17);
    53. Person p2("B", 19);
    54. Person p3("C", 21);
    55. Person p4("D", 23);
    56. Person p5("E", 25);
    57. v1.push_back(p3);
    58. v1.push_back(p2);
    59. v1.push_back(p1);
    60. v2.push_back(p2);
    61. v2.push_back(p3);
    62. v2.push_back(p4);
    63. v2.push_back(p5);
    64. // 先对容器进行排序
    65. sort(v1.begin(), v1.end(), Person_sort());
    66. sort(v2.begin(), v2.end(), Person_sort());
    67. vectorv_target; // 目标容器
    68. v_target.resize(v1.size() + v2.size()); // 两个容器大小和
    69. vector::iterator EndIt = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target.begin(), Person_sort());
    70. for_each(v_target.begin(), EndIt, PrintVector); // 遍历
    71. cout << endl;
    72. }
    73. int main() {
    74. test01();
    75. test02();
    76. system("pause");
    77. return 0;
    78. }

    运行结果:

    •  两个集合必须是有序序列
    • 目标容器开辟空间需要两个容器相加
    • set_union 返回值是并集最后一个元素的位置

    set_difference

    功能

    • 求两个集合(有序序列)的差集

    差集

    • v1 和 v2 的差集,找的是 v1 里有但 v2 里没有的元素(v1 特有的数
    • v2 和 v1 的差集,找的是 v2 里有但 v1 里没有的元素(v2 特有的数

    函数原型

    set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    beg1 —— 容器 1 开始迭代器

    end1 —— 容器 1 结束迭代器

    beg2 —— 容器 2 开始迭代器

    end2 —— 容器 2 结束迭代器

    dest  —— 目标容器开始迭代器

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. class Person {
    7. public:
    8. Person(string name, int age) :m_Name(name), m_Age(age) {}
    9. Person() {}
    10. string m_Name;
    11. int m_Age;
    12. };
    13. ostream& operator<<(ostream& cout, const Person& p) {
    14. cout << p.m_Name << " " << p.m_Age << endl;
    15. return cout;
    16. }
    17. template<typename T>
    18. void PrintVector(const T& x) {
    19. cout << x << " ";
    20. }
    21. // 内置数据类型差集
    22. void test01() {
    23. vector<int>v1; // 有序
    24. vector<int>v2; // 有序
    25. v1.push_back(10);
    26. v1.push_back(20);
    27. v1.push_back(30);
    28. v1.push_back(40);
    29. v2.push_back(30);
    30. v2.push_back(40);
    31. v2.push_back(50);
    32. v2.push_back(60);
    33. cout << "v1 与 v2 的差集:";
    34. vector<int>v_target1; // 目标容器
    35. v_target1.resize(max(v1.size(), v2.size())); // 容器大小
    36. vector<int>::iterator EndIt1 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target1.begin());
    37. for_each(v_target1.begin(), EndIt1, PrintVector<int>);
    38. cout << endl;
    39. cout << "v1 与 v2 的差集:";
    40. vector<int>v_target2; // 目标容器
    41. v_target2.resize(max(v1.size(), v2.size())); // 容器大小
    42. vector<int>::iterator EndIt2 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), v_target2.begin());
    43. for_each(v_target2.begin(), EndIt2, PrintVector<int>);
    44. cout << endl;
    45. }
    46. // 年龄排序仿函数
    47. class Person_sort {
    48. public:
    49. bool operator()(const Person& p1, const Person& p2) {
    50. return (p1.m_Age < p2.m_Age); // m_Age 降序
    51. }
    52. };
    53. // 自定义数据类型差集
    54. void test02() {
    55. vectorv1; // 有序
    56. vectorv2; // 有序
    57. Person p1("A", 22);
    58. Person p2("B", 21);
    59. Person p3("C", 20);
    60. Person p4("D", 19);
    61. Person p5("E", 18);
    62. v1.push_back(p1);
    63. v1.push_back(p2);
    64. v1.push_back(p3);
    65. v2.push_back(p3);
    66. v2.push_back(p4);
    67. v2.push_back(p5);
    68. sort(v1.begin(), v1.end(), Person_sort()); // 排序
    69. sort(v2.begin(), v2.end(), Person_sort()); // 排序
    70. cout << "v1 和 v2 的差集:" << endl;
    71. vectorv_target1;
    72. v_target1.resize(max(v1.size(), v2.size()));
    73. vector::iterator EndIt1 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v_target1.begin(), Person_sort());
    74. for_each(v_target1.begin(), EndIt1, PrintVector);
    75. cout << endl;
    76. cout << "v2 与 v1 的差集:" << endl;;
    77. vectorv_target2;
    78. v_target2.resize(max(v1.size(), v2.size()));
    79. vector::iterator EndIt2 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), v_target2.begin(), Person_sort());
    80. for_each(v_target2.begin(), EndIt2, PrintVector);
    81. cout << endl;
    82. }
    83. int main() {
    84. test01();
    85. test02();
    86. system("pause");
    87. return 0;
    88. }

    运行结果:

    •  两个容器需要是有序序列
    • 目标容器开辟空间大小取两个容器中大的
  • 相关阅读:
    第一篇:mybatis源码入门
    Flink状态Checkpoints检查点设置
    Git 用法指导
    06-jQuery中的防抖和节流
    基于MATLAB的指纹识别算法仿真实现
    双重队列问题
    C语言进阶 文件操作知识(上)
    Python之基础数据类型(二)
    【LeetCode刷题】--12.整数转罗马数字
    Redis 是什么?
  • 原文地址:https://blog.csdn.net/xuan3215/article/details/126230117