您的位置:首页 > 其它

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

2012-04-27 09:32 441 查看
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));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: