vector/set集合-交集并集差集对称差

Posted crystar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vector/set集合-交集并集差集对称差相关的知识,希望对你有一定的参考价值。

函数简介

这些函数主要用于vector/set进行交集、并集、差集、对称差集的运算,他们包含在< algorithm >头文件内。

函数原型

交集 (set_intersection)

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2,
                    OutputIterator 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);

该函数用于求两个集合的交集,例如{1,2,3,4}和{2,3,4,5}的交集为{2,3,4}。
函数的返回值:结果集合的结束位置的back_insert_iterator(迭代器)

并集 (set_union)

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2,
                    OutputIterator 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);

该函数用于求两个集合的交集,例如:集合{1,2,3,7,9}和{3,4,5,7}的并集为{1,2,3,4,5,7}。

差集(set_difference)

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2,
                    OutputIterator 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);

该函数用于求两个集合的差集,结果集合中包含所有属于第一个集合但不属于第二个集合的元素。例如:集合{1,2,3,7,9}和{3,4,5,7}的差集为{1,2,9}。

对称差集 (set_symeetric_difference)

template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2,
                    OutputIterator 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);

对称差集是除去两集合相同的元素后,两集合其他元素组成的集合。
例如:集合{1,2,3,7,9}和{3,4,5,7}的对称差为{1,2,4,5,9}。

函数参数

first1,end1 -- 第一个集合的起始位置
first2,end2 -- 第二个集合的起始位置
result -- 结果集合 (使用inserter(result,reult.begin())进行插入)

时间复杂度

在 cplusplus.com 内给出了函数的具体实现方式,这里贴出来交集的函数实现。

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);
}

可以看到实现方式为双指针,所以时间复杂度为(O(n))。-- 自己猜测的,如果有不同意见欢迎提出。

注意事项

如果结果集合并未分配空间的话则必须使用inserter(result,reult.begin()进行插入,但是如果提前分配大小,则只需要表明插入的起始位置即可。
集合运算注意的点:
1、第一个算法需要保证第一集合和第二集合有序,并从小到大排序,内部使用默认“<”操作符比较元素大小。
2.第二个算法需要保证第一集合和第二集合友续,排序方式按照Compare确定,内部使用Compare比较元素大小。

示例

由于这些函数大致相同,只有作用不同,所以这里只以交集为例。

示例一(未提前分配内存空间):

#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
    vector<int> v1{1,2,3,4,5,6};
    vector<int> v2{1,5,6,7,8};
    vector<int> c;
    set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),inserter(c,c.begin()));
    for (auto x : c)
    {
        cout << x << endl;
    }
    return 0;
}

输出:

1
5
6

示例二(提前分配内存空间):

#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
    vector<int> v1{1,2,3,4,5,6};
    vector<int> v2{1,5,6,7,8};
    vector<int> c(10);
    set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),c.begin());
    for (auto x : c)
    {
        cout << x << endl;
    }
    return 0;
}

输出:

1
5
6
0
0
0
0
0
0
0

当然我们并不可能自己一个一个去数结果集合内有多少个数(能自己去数,那要这个函数干嘛),所以我们必须再进行一步操作。

auto it=set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),c.begin());
c.resize(it-c.begin());

本随笔部分内容借鉴于该博客








以上是关于vector/set集合-交集并集差集对称差的主要内容,如果未能解决你的问题,请参考以下文章

C++拾取——stl标准库中集合交集并集差集对称差方法

两个集合求对称差集

对比集合Set | 详解Pandas的DataFrame如何做交集并集差集与对称差集

Python求两个list的交集并集补集对称差集的两种方法

python里面集合的集合的交并差和对称差集的求法。

SQL集合运算:差集、交集、并集