算法篇!带你领略STL的set算法与heap算法<algorithm>

  • STL标准没有区分基本算法或复杂算法,但是SGI却把一些常用的基本算法定义在<stl_algobase.h>中其他算法定义于<stl_algo.h>中。set与heap算法都定义在<stl_algo.h>中的
  • 应用层使用的头文件<algorithm>包含<stl_algobase.h>与<stl_algo.h>
  • heap算法已经在另一篇文章中介绍了,所以本文介绍的都是set算法。heap算法参阅:https://blog.csdn.net/qq_41453285/article/details/103631649
  • 本文介绍的算法有:
    • 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)
  • 每种算法都提供两个版本

一、set_union

  • 功能:该算法可以构造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;
}


  • 我是小董,V公众点击"笔记白嫖"解锁更多【C++ STL源码剖析】资料内容。

相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页