C++系列内容的学习目录                                 →                            \rightarrow                 →​ ​​C++学习系列内容汇总​​。



6. 常用集合算法

  学习目标: 掌握常用的集合算法。

  算法简介:

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

  例如,有容器v1和容器v2,其中v1中有元素0、1、2、3、4、5、6、7、8、9;v2中有元素5、6、7、8、9、10、11、12、13、14。v1和v2的交集、并集和差集如下图所示。

C++提高编程(五)—— STL常用算法(6) :常用集合算法_常用集合算法

6.1 set_intersection

  功能描述: 求两个容器的交集。

  函数原型:​set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);​

        // 求两个集合的交集

        // 注意:两个集合必须是有序序列

        // beg1 容器1开始迭代器

        // end1 容器1结束迭代器

        // beg2 容器2开始迭代器

        // end2 容器2结束迭代器

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

  实例如下所示。

#includeusing namespace std;#include;#include//常用集合算法:set_intersectionvoid myPrint(int val){
cout << val << " ";}void test01(){
vector<int>v1;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); //0~9
v2.push_back(i + 5); //5~14
}
cout << "v1:";
for_each(v1.begin(), v1.end(), myPrint);
cout << endl;
cout << "v2:";
for_each(v2.begin(), v2.end(), myPrint);
cout << endl;

//目标容器(需要提前开辟空间,最特殊情况为大容器包含小容器,开辟空间取小容器的size即可)
vector<int>vTarget;

vTarget.resize(min(v1.size(),v2.size())); //开辟空间(取小容器的size,可能会比交集的size大一些)

//获取交集
cout << "v1和v2的交集:";
vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

for_each(vTarget.begin(), itEnd, myPrint); //结束迭代器选择求交集得到的结束迭代器,而不是目标容器的结束迭代器,因为目标容器的size可能会比交集的size偏大一些
cout << endl;}int main(){
test01();

system("pause");

return 0;}

v1:0 1 2 3 4 5 6 7 8 9

v2:5 6 7 8 9 10 11 12 13 14

v1和v2的交集:5 6 7 8 9

  总结: 1. 求交集的两个集合必须是有序序列;

      2. 目标容器开辟空间需要从两个容器中取小值

      3. set_intersection返回值是交集中最后一个元素的位置。

6.2 set_union

  功能描述: 求两个集合的并集。

  函数原型:​set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);​

        // 求两个集合的并集

        // 注意:两个集合必须是有序序列

        // beg1 容器1开始迭代器

        // end1 容器1结束迭代器

        // beg2 容器2开始迭代器

        // end2 容器2结束迭代器

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

  实例如下所示。

#includeusing namespace std;#include;#include//常用集合算法:set_unionvoid myPrint(int val){
cout << val << " ";}void test01(){
vector<int>v1;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); //0~9
v2.push_back(i + 5); //5~14
}
cout << "v1:";
for_each(v1.begin(), v1.end(), myPrint);
cout << endl;
cout << "v2:";
for_each(v2.begin(), v2.end(), myPrint);
cout << endl;

//目标容器(需要提前开辟空间, 最特殊情况为两个容器没有交集,开辟空间取两个容器的size之和)
vector<int>vTarget;

vTarget.resize(v1.size() + v2.size()); //开辟空间(取两个容器的size之和,可能会比并集的size大一些)

//获取并集
cout << "v1和v2的并集:";
vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

for_each(vTarget.begin(), itEnd, myPrint); //结束迭代器选择求并集得到的结束迭代器,而不是目标容器的结束迭代器,因为目标容器的size可能会比并集的size偏大一些
cout << endl;}int main(){
test01();

system("pause");

return 0;}

v1:0 1 2 3 4 5 6 7 8 9

v2:5 6 7 8 9 10 11 12 13 14

v1和v2的并集:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

  总结: 1. 求并集的两个集合必须是有序序列;

      2. 目标容器开辟空间需要将两个容器相加

      3. set_union返回值既是并集中最后一个元素的位置。

6.3 set_difference

  功能描述: 求两个集合的差集。

  函数原型:​set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);​

        // 求两个集合的差集

        // 注意:两个集合必须是有序序列

        // beg1 容器1开始迭代器

        // end1 容器1结束迭代器

        // beg2 容器2开始迭代器

        // end2 容器2结束迭代器

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

  实例如下所示。

#includeusing namespace std;#include;#include//常用集合算法:set_differencevoid myPrint(int val){
cout << val << " ";}void test01(){
vector<int>v1;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); //0~9
v2.push_back(i + 5); //5~14
}
cout << "v1:";
for_each(v1.begin(), v1.end(), myPrint);
cout << endl;
cout << "v2:";
for_each(v2.begin(), v2.end(), myPrint);
cout << endl;

//目标容器(需要提前开辟空间, 最特殊情况为两个容器没有交集,开辟空间取大容器的size即可)
vector<int>vTarget;

vTarget.resize(max(v1.size(), v2.size())); //开辟空间(取大容器的size,可能会比差集的size大一些)

//获取差集
cout << "v1和v2的差集:";
vector<int>::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

for_each(vTarget.begin(), itEnd, myPrint); //结束迭代器选择求差集得到的结束迭代器,而不是目标容器的结束迭代器,因为目标容器的size可能会比差集的size偏大一些
cout << endl;

cout << "v2和v1的差集:";
itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint);
cout << endl;}int main(){
test01();

system("pause");

return 0;}

v1:0 1 2 3 4 5 6 7 8 9

v2:5 6 7 8 9 10 11 12 13 14

v1和v2的差集:0 1 2 3 4

v2和v1的差集:10 11 12 13 14

  总结: 1. 求差集的两个集合必须的有序序列;

      2. 目标容器开辟空间需要从两个容器取较大值

      3. set_difference返回值既是差集中最后一个元素的位置。