STL源码剖析学习十四:算法之set相关算法

STL中定义的set要求元素不得重复且已经排序
set算法要求的都是有序区间,但元素可以重复出现
另外提供的hash版本的set因为其元素无序,因此不能作为set函数的参数

 

set算法前4个参数分别表示两个区间,第五个参数表示存放结果的区间的起始位置。
还允许用户指定a<b的意义,判断两个元素是否相等全靠小于运算

 

先给个例子

#include<set>
#include<iostream>
#include<algorithm>
#include<iterator>
using namespace std;

template <class T>
struct display
{
    void operator()(const T& x)
    {
        cout<<x<<" ";
    }
};

int main()
{
    int ia1[6] = {1,3,5,7,9,11};
    int ia2[7] = {1,2,3,5,8,13,1};

    multiset<int> s1(ia1, ia1+6);
    multiset<int> s2(ia2, ia2+7);

    for_each(s1.begin(), s1.end(), display<int>());
    cout<<endl;
    for_each(s2.begin(), s2.end(), display<int>());
    cout<<endl;

    cout<<"union"<<endl;
    set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
    cout<<endl;

    cout<<"intersection"<<endl;
    set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
    cout<<endl;

    cout<<"difference"<<endl;
    set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
    cout<<endl;

    cout<<"difference"<<endl;
    set_difference(s2.begin(), s2.end(), s1.begin(), s1.end(), ostream_iterator<int>(cout, " "));
    cout<<endl;

    cout<<"symmetric difference"<<endl;
    set_symmetric_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
    cout<<endl;

    system("pause");
}

 


求两个集合的并集,是一种稳定操作,输入区间内的每个元素相对顺序都不会改变

set_union(first1, last1, first2, last2, result)
{
    while(first1!=last1 && first2!=last2)
    {
        //两个容器内的元素相比较,把较小者放入结果容器中,并向前移动迭代器
        //如果两个元素相等则写入结果中,同时移动两个迭代器
        if(*first1<*first2)
        {
            *result = *first;
            ++first1;
        }
        else if(*first2<*first1)
        {
            *result = *first;
            ++first2;
        }
        else
        {
            *result = *first1;
            ++first1;
            ++first2;
        }
        ++result;
    }
    //把剩余的元素都拷贝进结果中
    //copy返回迭代器指向目标容器的插入元素的最后一个元素的下一个元素
    return copy(first2, last2, copy(first1, last1, result));
}

 


求交集,若某个值在s1中出现n次,在s2中出现m次,在输出中会出现min(m,n)次

set_intersection(first1, last1, first2, last2, result)
{
    while(first1!=last1 && first2!=last2)
    {
        if(*first1<*first2)
        {
            ++first1;
        }
        else if(*first2<*first1)
        {
            ++first2;
        }
        else
        {
            *result = *first1;
            ++first1;
            ++first2;
            ++result;
        }
    }
    return result;
}

 

求差集,若某个值在s1中出现n次,在s2中出现m次,在输出中会出现max(n-m,0)次

set_difference(first1, last1, first2, last2, result)
{
    while(first1!=last1 && first2!=last2)
    {
        if(*first1<*first2)
        {
            *result = *first1;
            ++first;
            ++result;
        }
        else if(*first2<*first1)
        {
            ++*first2;
        }
        else
        {
            ++first1;
            ++first2;
        }
    }
    return copy(first1, last1, result);
}

 

求对称差集 (s1-s2)∪(s2-s1)若某个值在s1中出现n次,在s2中出现m次,在输出中会出现abs(m-n)次

set_symmetric_difference(first1, last1, first2, last2, result)
{
    while(first1!=last1 && first2!=last2)
    {
        if(*first1<*first2)
        {
            *result = *first1;
            ++first1;
            ++result;
        }
        if(*first2<*first1)
        {
            *result = *first2;
            ++first2;
            ++result;
        }
        else
        {
            ++first1;
            ++first2;
        }
    }
    return copy(first1, last1, copy(first2, last2, result));
}

 

posted @ 2012-04-27 09:32  w0w0  阅读(382)  评论(0编辑  收藏  举报