STL源码剖析——set相关算法

简介

  • 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值