STL源码剖析——set相关算法
程序员文章站
2022-03-23 11:33:48
...
简介
-
STL一共提供了四种与set(集合)相关的算法,set必须是有序区间,元素值可以重复。换句话说,它们可以接受STL的set/multiset容器作为输入区间。
- 并集(union)
- 交集(intersection)
- 差集(difference)
- 对称差集(symmetric difference)
算法——set_union
算法set_union可构造s1、s2之并集。set_union是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变。
版本一
template <class InputIterator1, class InputIterator2,
class OutputIterator>
OutputIterator set_union (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result){
{
while (first1!=last1 && first2!=last2)
{
if (first1==last1) return std::copy(first2,last2,result);
if (first2==last2) return std::copy(first1,last1,result);
if (*first1<*first2) { *result = *first1; ++first1; }
else if (*first2<*first1) { *result = *first2; ++first2; }
else { *result = *first1; ++first1; ++first2; }
++result;
}
return copy(first2,last2,copy(first1,last1,result));
}
- 版本二:可自定义仿函数
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
算法——set_intersection
算法set_intersection可构造s1、s2之交集。set_intersection是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变。
版本一
template <class InputIterator1, class InputIterator2,
class OutputIterator>
OutputIterator set_intersection (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result){
{
while (first1!=last1 && first2!=last2)
{
if (*first1<*first2) ++first1;
else if (*first2<*first1) ++first2;
else {
*result = *first1;
++result; ++first1; ++first2;
}
}
return result;
}
- 版本二:可自定义仿函数
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_intersection (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result, Compare comp);
算法——set_difference
算法set_difference可构造s1、s2之差集。set_difference是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变。
版本一
template <class InputIterator1, class InputIterator2,
class OutputIterator>
OutputIterator set_difference (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result){
{
while (first1!=last1 && first2!=last2)
{
if (*first1<*first2) { *result = *first1; ++result; ++first1; }
else if (*first2<*first1) ++first2;
else { ++first1; ++first2; }
}
return std::copy(first1,last1,result);
}
- 版本二:可自定义仿函数
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_difference (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result, Compare comp);
算法——set_symmetric_difference
算法set_symmetric_difference可构造s1、s2之对称差。
set_symmetric_difference是一种稳定操作,意思是输入区间内的每个元素的相对顺序都不会改变。版本一
template <class InputIterator1, class InputIterator2,
class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result){
{
while (first1!=last1 && first2!=last2)
{
if (*first1<*first2) { *result = *first1; ++result; ++first1; }
else if (*first2<*first1) { *result = *first2; ++result; ++first2; }
else { ++first1; ++first2; }
}
return std::copy(first2,last2,copy(first1,last1,result));
}
- 版本二:可自定义仿函数
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_symmetric_difference (InputIterator1 first1,
InputIterator1 last1,InputIterator2 first2,
InputIterator2 last2,OutputIterator result, Compare comp);
- 例:仿照库函数实现
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
void set_union(const multiset<int>& s1, const multiset<int>& s2, multiset<int>& s) {
auto first1 = s1.begin();
auto end1 = s1.end();
auto first2 = s2.begin();
auto end2 = s2.end();
while (first1 != end1 && first2 != end2) {
if (*first1 < *first2) {
s.insert(*first1);
++first1;
}else if (*first1 > *first2) {
s.insert(*first2);
++first2;
}
else {
s.insert(*first1);
++first1;
++first2;
}
}
if (first1 != end1) {
while (first1 != end1) {
s.insert(*first1);
++first1;
}
}
else if (first2 != end2) {
while (first2 != end2) {
s.insert(*first2);
++first2;
}
}
}
void set_intersection(const multiset<int>& s1, const multiset<int>& s2, multiset<int>& s) {
auto first1 = s1.begin();
auto end1 = s1.end();
auto first2 = s2.begin();
auto end2 = s2.end();
while (first1 != end1 && first2 != end2) {
if (*first1 < *first2) {
++first1;
}
else if (*first1 > *first2) {
++first2;
}
else {
s.insert(*first1);
++first1;
++first2;
}
}
}
void set_difference(const multiset<int>& s1, const multiset<int>& s2, multiset<int>& s) {
auto first1 = s1.begin();
auto end1 = s1.end();
auto first2 = s2.begin();
auto end2 = s2.end();
while (first1 != end1 && first2 != end2) {
if (*first1 < *first2) {
s.insert(*first1);
++first1;
}
else if (*first1 > *first2) {
++first2;
}
else {
++first1;
++first2;
}
}
if (first1 != end1) {
while (first1 != end1) {
s.insert(*first1);
++first1;
}
}
}
void set_symmetric_difference(const multiset<int>& s1, const multiset<int>& s2, multiset<int>& s) {
auto first1 = s1.begin();
auto end1 = s1.end();
auto first2 = s2.begin();
auto end2 = s2.end();
while (first1 != end1 && first2 != end2) {
if (*first1 < *first2) {
s.insert(*first1);
++first1;
}
else if (*first1 > *first2) {
s.insert(*first2);
++first2;
}
else {
++first1;
++first2;
}
}
if (first1 != end1) {
while (first1 != end1) {
s.insert(*first1);
++first1;
}
}
else if (first2 != end2) {
while (first2 != end2) {
s.insert(*first2);
++first2;
}
}
}
void output(const multiset<int>& s) {
for (auto it : s) {
cout << it << " ";
}
cout << endl;
}
int main(int argc, char* argv[]) {
multiset<int> s1{ 1,3,5,7,9 ,11 };
multiset<int> s2{ 1,1,2,3,5,8,13 };
multiset<int> s3;
set_union(s1, s2, s3);
output(s3);
multiset<int> s4;
set_intersection(s1, s2, s4);
output(s4);
multiset<int> s5;
set_difference(s1, s2, s5);
output(s5);
multiset<int> s6;
set_symmetric_difference(s1, s2, s6);
output(s6);
getchar();
return 0;
}
上一篇: STL源码剖析笔记(heap)
下一篇: 《STL源码剖析》STL空间配置器