c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器。

set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。

c++ stl集合set介绍

c++ stl集合(Set)是一种包含已排序对象的关联容器。set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。

1) 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素

2) 不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数

3) 元素比较动作只能用于型别相同的容器(即元素和排序准则必须相同)

set模板原型://Key为元素(键值)类型

1
template <class Key, class Compare=less<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) >

从原型可以看出,可以看出比较函数对象及内存分配器采用的是默认参数,因此如果未指定,它们将采用系统默认方式。

set的各成员函数列表如下:

c++ stl容器set成员函数:begin()--返回指向第一个元素的迭代器

c++ stl容器set成员函数:clear()--清除所有元素

c++ stl容器set成员函数:count()--返回某个值元素的个数

c++ stl容器set成员函数:empty()--如果集合为空,返回true

c++ stl容器set成员函数:end()--返回指向最后一个元素的迭代器

c++ stl容器set成员函数:equal_range()--返回集合中与给定值相等的上下限的两个迭代器

c++ stl容器set成员函数:erase()--删除集合中的元素

c++ stl容器set成员函数:find()--返回一个指向被查找到元素的迭代器

c++ stl容器set成员函数:get_allocator()--返回集合的分配器

c++ stl容器set成员函数:insert()--在集合中插入元素

c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

c++ stl容器set成员函数:key_comp()--返回一个用于元素间值比较的函数

c++ stl容器set成员函数:max_size()--返回集合能容纳的元素的最大限值

c++ stl容器set成员函数:rbegin()--返回指向集合中最后一个元素的反向迭代器

c++ stl容器set成员函数:rend()--返回指向集合中第一个元素的反向迭代器

c++ stl容器set成员函数:size()--集合中元素的数目

c++ stl容器set成员函数:swap()--交换两个集合变量

c++ stl容器set成员函数:upper_bound()--返回大于某个值元素的迭代器

c++ stl容器set成员函数:value_comp()--返回一个用于比较元素间的值的函数

常用操作
1.元素插入:insert()
2.中序遍历:类似vector遍历(用迭代器)
3.反向遍历:利用反向迭代器reverse_iterator。
    例:

 set<int> s;
......
set<int>::reverse_iterator rit;
for(rit=s.rbegin();rit!=s.rend();rit++)

4.元素删除:与插入一样,可以高效的删除,并自动调整使红黑树平衡。

 set<int> s;
s.erase(); //删除键值为2的元素
s.clear();

5.元素检索:find(),若找到,返回该键值迭代器的位置,否则,返回最后一个元素后面一个位置。

 set<int> s;
set<int>::iterator it;
it = s.find(); //查找键值为5的元素
if (it != s.end()) //找到
cout << *it << endl;
else //未找到
cout << "未找到";

6.自定义比较函数
    (1)元素不是结构体:
        例:
        //自定义比较函数myComp,重载“()”操作符

 struct myComp
{
bool operator()(const your_type &a, const your_type &b){
return a.data - b.data > ;
}
}
set<int, myComp>s;
......
set<int, myComp>::iterator it; erator it;

(2)如果元素是结构体,可以直接将比较函数写在结构体内。
        例:

 struct Info
{
string name;
float score;
//重载“<”操作符,自定义排序规则
bool operator < (const Info &a) const
{
//按score从大到小排列
return a.score<score;
}
}
set<Info> s;
......
set<Info>::iterator it;
 #include<iostream>
#include<set>
using namespace std;
//set插入元素操作
int main()
{
//定义一个int型集合对象s,当前没有任何元素.由www.169it.com搜集整理
set<int> s;
s.insert(); //第一次插入8,可以插入
s.insert();
s.insert();
s.insert();
s.insert(); //第二次插入8,重复元素,不会插入
set<int>::iterator it; //定义前向迭代器
for(it=s.begin();it!=s.end();it++)
cout<<*it<<endl;
system("pause");
return ;
}

其他用法如下

 #include <iostream>
#include <iterator>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
set<int> eg1;
eg1.insert();
eg1.insert();
eg1.insert();
eg1.insert(); //元素1因为已经存在所以set中不会再次插入1
eg1.insert();
eg1.insert();
//遍历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() == eg1.end())//find()函数可以查找元素是否存在
cout << "200 isn't in the set eg1" << endl; set<int> eg2;
for (int i = ; i < ; 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 ;
} 下面给出一个关键字类型为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) < ;
}
}; int main()
{
const int N = ;
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 ;
} 其中的ltstr也可以这样定义
class ltstr
{
public:
bool operator() (const char* s1, const char*s2)const
{
return strcmp(s1, s2) < ;
}
}; 更加通用的应用方式那就是数据类型也是由用户自定义的类来替代,比较的函数自定义,甚至可以加上二级比较,比如首先按照总分数排序,对于分数相同的按照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 = ; a.score = ; a.name = "bill";
b.id = ; b.score = ; b.name = "mary";
c.id = ; c.score = ; 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 ;
}

set--常见成员函数及基本用法的更多相关文章

  1. C++ 指向类成员函数指针的用法(转自维基百科)

    类成员函数指针 类成员函数指针(member function pointer),是C++语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息. 目录 1 语法 ...

  2. C++成员函数指针错误用法警示(成员函数指针与高性能的C++委托,三篇),附好多评论

    今天做一个成绩管理系统的并发引擎,用Qt做的,仿照QtConcurrent搞了个模板基类.这里为了隐藏细节,隔离变化,把并发的东西全部包含在模板基类中.子类只需注册需要并发执行的入口函数即可在单独线程 ...

  3. c++ 类模版、成员函数模版、函数模版 用法

    C++函数模版与类模版. template <class T> void SwapFunction(T &first, T &second){ }//函数模版 templa ...

  4. 直接调用类成员函数地址(用汇编取类成员函数的地址,各VS版本还有所不同)

    在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法. ...

  5. 介绍了如何取成员函数的地址以及调用该地址:C++

    摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...

  6. c++ 类中模版成员函数

    C++函数模版与类模版. template <class T> void SwapFunction(T &first, T &second){ }//函数模版 templa ...

  7. (C/C++学习)3.C++中cin的成员函数(cin.get();cin.getine()……)

    说明:流输入运算符,在一定程度上为C++程序的开发提供了很多便利,我们可以避免C语言那种繁琐的输入格式,比如在输入一个数值时,还需指定其格式,而cin以及cout则不需要.但是cin也有一些缺陷,比如 ...

  8. c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例

    c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...

  9. Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:

    Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...

随机推荐

  1. Lucence.Net+添加关键词+分页+排序

    1.使用queryparser完成解析搜索请求 2.基本格式如: QueryParser parser=new QueryParser("字段名称","分析器实例&quo ...

  2. cocos2d-x教程1 hello world

    HelloworldScene.h #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos ...

  3. PhoneGap笔记-01 基本使用

    1. 环境配置 1.1 常用框架 jQuery Backbone.js dojo bootstrap kendo UI Sencha jQuery Mobile PhoneJS AngularJS I ...

  4. poj 3358

    /** 大意: 给定小数(p/q),求其循环节的大小和循环节开始的位置 解法: 若出现循环 ai*2^m= aj%p; 即 2^m %p =1 若2与p 互素,则可由欧拉函数的, 不互素,需将其转化为 ...

  5. 转:什么是FOUC?如何避免FOUC?

    今天了解了一个新的名词叫做 FOUC 浏览器样式闪烁,之前也听说过一些类似的东西,比如样式突变等等,但这东西竟然有学名的.. 什么是FOUC(文档样式短暂失效)?如果使用import方法对CSS进行导 ...

  6. 自动输入用户名和密码用于telnet的shell

    http://blog.sina.com.cn/s/blog_45497dfa0100l4cf.html

  7. 使用 RMI + ZooKeeper 实现远程调用框架

    目录[-] 1 发布 RMI 服务1.1 定义一个 RMI 接口1.2 编写 RMI 接口的实现类1.3 通过 JNDI 发布 RMI 服务2 调用 RMI 服务3 RMI 服务的局限性4 使用 Zo ...

  8. haproxy 超时自动重发

    timeout connect 5000 timeout client 50000 timeout server 50000 timeout check 5s stats refresh 30s Ap ...

  9. hdoj 1166 敌兵布阵(树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 思路分析:该问题为动态连续和查询问题,使用数组数组可以解决:也可使用线段树解决该问题: 代码如下 ...

  10. 利用Crowbar抓取网页异步加载的内容 [Python俱乐部]

    利用Crowbar抓取网页异步加载的内容 [Python俱乐部] 利用Crowbar抓取网页异步加载的内容 在做 Web 信息提取.数据挖掘的过程中,一个关键步骤就是网页源代码的获取.但是出于各种原因 ...