- STL标准没有区分基本算法或复杂算法,但是SGI却把一些常用的基本算法定义在<stl_algobase.h>中,其他算法定义于<stl_algo.h>中。set与heap算法都定义在<stl_algo.h>中的
- 应用层使用的头文件<algorithm>包含<stl_algobase.h>与<stl_algo.h>
- heap算法已经在另一篇文章中介绍了,所以本文介绍的都是set算法。heap算法参阅:javascript:void(0)
- 本文介绍的算法有:
- set_union
- set_intersection
- set_difference
- set_symmetric_difference
set算法总体概述
- STL一共提供了4种与set相关的算法,分别为:并集(union)、交集(intersection)、差集(difference)、对称差集(symmetric_difference)
- 注意:此set与set容器不是一个东西。这个set是数学概念的上的
- 这些算法接受的区间必须是有序区间,因此可以使用set/multiset容器作为输入区间,但是不能以hash_set或hash_multiset作为输入容器,因为其内的元素并未呈现排序状态
- 4个算法都至少有四个参数,分别为两个set区间。下面以S1代表第一区间(first1,last1),以S2代表第二区间(first2,last2)
- 每种算法都提供两个版本
- 功能:该算法可以构造S1、S2的并集,也就是构造出集合S1∪S2
- 返回值:返回一个迭代器,指向输出区间的尾端
- 由于S1和S2内的每个元素都不必唯一,因此,如果某个值在S1出现n次,在S2出现m次,那么该值在输出区间中会出现max(m,n)次,其中n个来自S1,其余来自S2
- set_union是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变
版本①
- 版本①为默认版本,第一版本使用operator<进行比较
版本②
- 版本②采用仿函数comp进行比较。此处就不再列出
演示案例
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
int main()
{
int ia1[6] = { 1,3,5,7,9,11 };
int ia2[7] = { 1,1,2,3,5,8,13 };
multiset<int> S1(ia1, ia1 + 6);
multiset<int> S2(ia2, ia2 + 7);
std::cout << "Union of S1 and S2: ";
set_union(S1.begin(), S1.end(),
S2.begin(), S2.end(),
ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
二、set_intersection
- 功能:该算法可以构造S1、S2的交集,也就是构造出集合S1∩S2
- 返回值:返回一个迭代器,指向输出区间的尾端
- 由于S1和S2内的每个元素都不必唯一,因此,如果某个值在S1出现n次,在S2出现m次,那么该值在输出区间中会出现min(m,n)次,并且全部来自S1
- set_intersection是一种稳定操作,意思是输出区间内的每个元素的相对顺序都和S1内的相对顺序相同
版本①
- 版本①使用operator<进行比较
版本②
- 版本②采用仿函数comp进行比较
演示案例
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
int main()
{
int ia1[6] = { 1,3,5,7,9,11 };
int ia2[7] = { 1,1,2,3,5,8,13 };
multiset<int> S1(ia1, ia1 + 6);
multiset<int> S2(ia2, ia2 + 7);
std::cout << "Intersection of S1 and S2: ";
set_intersection(S1.begin(), S1.end(),
S2.begin(), S2.end(),
ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
三、set_difference
- 功能:该算法可以构造S1、S2的差集,也就是构造出集合S1-S2
- 此集合内含“出现于S1但不出现于S2”的每一个元素。S1、S2及其交集都是以排序区间表示
- 返回值:返回一个迭代器,指向输出区间的尾端
- 由于S1和S2内的每个元素都不必唯一,因此,如果某个值在S1出现n次,在S2出现m次,那么该值在输出区间中会出现max(n-m,0)次,并且全部来自S1
- set_difference是一种稳定操作,意思是输出区间内的每个元素的相对顺序都和S1内的相对顺序相同
版本①
- 版本①使用operator<进行比较
版本②
- 版本②采用仿函数comp进行比较
演示案例
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
int main()
{
int ia1[6] = { 1,3,5,7,9,11 };
int ia2[7] = { 1,1,2,3,5,8,13 };
multiset<int> S1(ia1, ia1 + 6);
multiset<int> S2(ia2, ia2 + 7);
std::cout << "Difference of S1 and S2 (S1-S2): ";
set_difference(S1.begin(), S1.end(),
S2.begin(), S2.end(),
ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
四、set_symmetric_difference
- 功能:该算法可以构造S1、S2的对称差集,也就是构造出集合(S1-S2)∪(S2-S1)
- 此集合内含“出现于S1但不出现于S2”以及“出现于S2但不出现于S1”的每一个元素。S1、S2及其交集都是以排序区间表示
- 返回值:返回一个迭代器,指向输出区间的尾端
- 由于S1和S2内的每个元素都不必唯一,因此,如果某个值在S1出现n次,在S2出现m次,那么该值在输出区间中会出现|n-m|次
- 如果n>m,输出区间内的最后n-m个元素将由S1复制而来
- 如果n<m,输出区间内的最后n-m个元素将由S2复制而来
- set_symmetric_difference是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变
版本①
- 版本①使用operator<进行比较
版本②
- 版本②采用仿函数comp进行比较
演示案例
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
int main()
{
int ia1[6] = { 1,3,5,7,9,11 };
int ia2[7] = { 1,1,2,3,5,8,13 };
multiset<int> S1(ia1, ia1 + 6);
multiset<int> S2(ia2, ia2 + 7);
std::cout << "Symmetric difference of S1 and S2: ";
set_symmetric_difference(S1.begin(), S1.end(),
S2.begin(), S2.end(),
ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}