C++学习 std::set作为一个有序集合
摘要:std::set作为标准库的一个关联容器,实现内部元素进行了排序,使用这特性可以对一组元素进行插入排序。std::set最初的设计是完成数学中“集合”的概念,它提供的接口也是如此。本文简单地介绍一下这一个标准库容器。为了使用std::set,我只需要如下:#include//定义一个整型数据的集合std::setint> set;如同所有的STL容器一样,
摘要:std::set作为标准库的一个关联容器,实现内部元素进行了排序,使用这特性可以对一组元素进行插入排序。std::set最初的设计是完成数学中“集合”的概念,它提供的接口也是如此。本文简单地介绍一下这一个标准库容器。
为了使用std::set,我只需要如下:
//定义一个整型数据的集合
std::set<int> set;
下面我会展示一些简单的使用示例,这些是示例非常简单,首先介绍那个“排序”的用法:
int array[5]={12, 34, 10, 98, 3};
const size_t array_size=sizeof(array)/sizeof(array[0]);
std::set<int> set;
for(size_t i=0; i<array_size;++i)
{
//把数据插入集合,数据自动排序
set.insert(array[i]);
}
//此时已经排序了,下面依次输出
std::set<int>::const_iterator b=set.begin();
for(; b!=set.end();++b)
{
std::cout<<*b << '\n';
}
在一般意识中,一个集合并没有太多的操作,所有在STL中,std::set也没有太多操作,它的排序是自动的,我们可以插入一个元素,也可以删除一个元素,也有迭代器。下面简单的示例包括std::set自身的多数的特性:
int array[5]={12, 34, 10, 98, 3};
const size_t array_size=sizeof(array)/sizeof(array[0]);
//一个新的定义容器的方法
std::set<int> set(array, array+array_size);
//插入一个元素
set.insert(23);
//移除一个元素
set.erase(10);
//移除一个元素不在集合中的元素
//此时什么也不做,n作为返回值将会是0
//指明没有元素移除
size_t n=set.erase(11);
//使用迭代器,找到一个元素
std::set<int>::const_iterator result=set.find(98);
std::set<int> other;
//交换两个集合的内容
std::swap(set, other);
//清除所有的内容
other.clear()
#include<set>
#include<iterator>
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
set<int> eg1;
eg1.insert(1);
eg1.insert(100);
eg1.insert(5);
eg1.insert(1); //元素1因为已经存在所以set中不会再次插入1
eg1.insert(10);
eg1.insert(9);
//遍历set,可以发现元素是有序的
set<int>::iterator set_iter=eg1.begin();
cout<<"Set named eg1:"<<endl;
for(;set_iter!=eg1.end();set_iter++) cout<<*set_iter<<" ";
cout<<endl;
//使用size()函数可以获得当前元素个数
cout<<"Now there are "<<eg1.size()<<" elements in the set eg1"<<endl;
if(eg1.find(200)==eg1.end())//find()函数可以查找元素是否存在
cout<<"200 isn't in the set eg1"<<endl;
set<int> eg2;
for(int i=6;i<15;i++)
eg2.insert(i);
cout<<"Set named eg2:"<<endl;
for(set_iter=eg2.begin(); set_iter!=eg2.end(); set_iter++)
cout<<*set_iter<<" ";
cout<<endl;
//获得两个set的并
set<int> eg3;
cout<<"Union(两个set的并集):";
set_union(eg1.begin(),
eg1.end(),
eg2.begin(),
eg2.end(),
insert_iterator<set<int> >(eg3, eg3.begin())
);//注意第五个参数的形式
copy(eg3.begin(), eg3.end(), ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的交,注意进行集合操作之前接收结果的set要调用clear()函数清空一下
eg3.clear();
set_intersection(eg1.begin(),
eg1.end(),
eg2.begin(),
eg2.end(),
insert_iterator<set<int> >(eg3,eg3.begin())
);
cout<<"Intersection:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的差
eg3.clear();
set_difference(eg1.begin(),
eg1.end(),eg2.begin(),
eg2.end(),
insert_iterator<set<int> >(eg3,eg3.begin())
);
cout<<"Difference:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的对称差,也就是假设两个集合分别为A和B那么对称差为AUB-A∩B
eg3.clear();
set_symmetric_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
return 0;
}
下面给出一个关键字类型为char*的示例代码
#include<iostream>
#include<iterator>
#include<set>
using namespace std;
struct ltstr
{
bool operator() (const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
int main()
{
const int N = 6;
const char* a[N] = {"isomer", "ephemeral", "prosaic",
"nugatory", "artichoke", "serif"};
const char* b[N] = {"flat", "this", "artichoke",
"frigate", "prosaic", "isomer"};
set<const char*,ltstr> A(a, a + N);
set<const char*,ltstr> B(b, b + N);
set<const char*,ltstr> C;
cout << "Set A: ";
//copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));
set<const char*,ltstr>::iterator itr;
for(itr=A.begin();itr!=A.end();itr++) cout<<*itr<<" ";
cout << endl;
cout << "Set B: ";
copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " "));
cout << endl;
cout << "Union: ";
set_union(A.begin(), A.end(), B.begin(), B.end(),
ostream_iterator<const char*>(cout, " "),
ltstr());
cout << endl;
cout << "Intersection: ";
set_intersection(A.begin(), A.end(), B.begin(),B.end(),ostream_iterator<const char*>(cout," "),ltstr());
cout<<endl;
set_difference(A.begin(), A.end(), B.begin(), B.end(),inserter(C, C.begin()),ltstr());
cout << "Set C (difference of A and B): ";
copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " "));
cout <<endl;
return 0;
}
其中的ltstr也可以这样定义
class ltstr
{
public:
bool operator() (const char* s1,const char*s2)const
{
return strcmp(s1,s2)<0;
}
};
更加通用的应用方式那就是数据类型也是由用户自定义的类来替代,比较的函数自定义,甚至可以加上二级比较,比如首先按照总分数排序,对于分数相同的按照id排序,下面是示例代码
#include<set>
#include<iostream>
using namespace std;
struct
{
int id;
int score;
string name;
};
struct compare
{
bool operator()(const Entity& e1,const Entity& e2)const {
if(e1.score<e2.score) return true;
else
if(e1.score==e2.score)
if(e1.id<e2.id) return true;
return false;
}
};
int main()
{
set<Entity,compare>s_test;
Entity a,b,c;
a.id=123;a.score=90;a.name="bill";
b.id=121;b.score=85;b.name="mary";
c.id=130;c.score=85;c.name="jerry";
s_test.insert(a);s_test.insert(b);s_test.insert(c);
set<Entity,compare>::iterator itr;
cout<<"Score List(ordered by score):\n";
for(itr=s_test.begin();itr!=s_test.end();itr++)
cout<<itr->id<<"---"<<itr->name<<"---"<<itr->score<<endl;
return 0;
}
更多推荐
所有评论(0)