(转)C++ STL set() 集合
set是STL中一种标准关联容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。set,顾名思义是“集合”的意思,在set中元素都是唯一的,而且默认情况下会对元素自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允许重复那么可以使用multiset
#include<set>
#include<iterator>
#include<iostream>
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_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 ;
}
set会对元素进行排序,那么问题也就出现了排序的规则是怎样的呢?上面的示例代码我们发现对int型的元素可以自动判断大小顺序,但是对char*就不会自动用strcmp进行判断了,更别说是用户自定义的类型了,事实上set的标准形式是set<Key, Compare, Alloc>,
| 参数 | 描述 | 默认值 |
|---|---|---|
| Key | 集合的关键字和值的类型 | |
| Compare | 关键字比较函数,它的参数类型key参数指定的类型,如果第一个参数小于第二个参数则返回true,否则返回false | less<Key> |
| Alloc | set的分配器,用于内部内存管理 | alloc |
下面给出一个关键字类型为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 Entity
{
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 ;
}
(转)C++ STL set() 集合的更多相关文章
- STL语法——集合:set 安迪的第一个字典(Andy's First Dictionary,UVa 10815)
Description Andy, , has a dream - he wants to produce his very own dictionary. This is not an easy t ...
- C++ STL Set 集合
前言 set是STL中的一种关联容器.集合具有无序性,互异性等特点.熟练使用STL中的set模板类,可以比较简单的解决一些编程问题. 关联容器:元素按照关键字来保存和访问,STL中的map,set就是 ...
- STL的集合set
集合: 集合是由元素组成的一个类,其成员可以是一个集合,也可以是一个原子,通常一个元素在一个集合中不能多次出现:由于对实现集合不是很理解,只简单写下已有的STL中的set集合使用: C++中set基本 ...
- 【STL】集合运算
STL中有可以实现交集.并集.差集.对称差集的算法. 使用前需要包含头文件: #include <algorithm> 注:使用计算交集和并集的算法必须保证参与运算的两个集合有序!!! 交 ...
- STL&&用法集合
.....STL是c++里很强势很好用的一系列容器(函数)之类的,之前一直不太会用,所以总是暴毙....想着快比赛了,是时候理一下这些东西了. -1.pair 存放两个基本元素的东西 定义方法: pa ...
- C++ STL set集合容器
汇总了一些set的常用语句,部分参考了这篇:http://blog.163.com/jackie_howe/blog/static/199491347201231691525484/ #include ...
- stl的集合set——安迪的第一个字典(摘)
set就是数学上的集合——每个元素最多只出现一次,和sort一样,自定义类型也可以构造set,但同样必须定义“小于”运算符 以下代码测试set中无重复元素 #include<iostream&g ...
- STL set集合用法总结(multiset)
2017-08-20 15:21:31 writer:pprp set集合容器使用红黑树的平衡二叉树检索树,不会将重复键值插入,检索效率高 logn 检索使用中序遍历,所以可以将元素从小到大排列出来 ...
- 单词数 (STL set集合)
单词数 Problem Description lily的好朋友xiaoou333近期非常空.他想了一件没有什么意义的事情.就是统计一篇文章里不同单词的总数.以下你的任务是帮助xiaoou333解决问 ...
随机推荐
- Vijos——P1137 组合数
https://vijos.org/p/1137 描述 组合公式 C=N!/(M!*(N-M)!). 问题是求 C 中不同的质因子的个数例如 N=7, M=4. C=7!/(3!*4!)=5040/( ...
- SVG动画实践篇-字母切换
git: https://github.com/rainnaZR/svg-animations/tree/master/src/pages/step2/letter.change 说明 这个页面实现了 ...
- java 图片加水印,设置透明度。说明非常具体
package com.yidao.common; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.aw ...
- JSP自己定义标签继承哪个类
JSP自己定义标签继承哪个类 解:JSP自己定义标签继承TagSupport
- 小白学phoneGap《构建跨平台APP:phoneGap移动应用实战》连载一(PhoneGap中的API)
之前本博连载过<构建跨平台APP:jQuery Mobile移动应用实战>一书.深受移动开发入门人员的喜爱. 从如今開始,连载它的孪生姐妹书phoneGap移动应用实战一书,希望以前是小白 ...
- ios 清理缓存(EGO)
一段清理缓存的代码例如以下: dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,) , ^{ NSSt ...
- DataGridView.DataSource= list(Of T)
注:本文样例的代码承接上篇文章:DataTable填充实体类返回泛型集合. 在D层查询完毕之后.我们将DataTable转化为泛型集合.然后经过中间各层,返回U层.到了这里,问题来了.我们这时候要将这 ...
- 机器学习(Machine Learning)&深度学习(Deep Learning)资料
机器学习(Machine Learning)&深度学习(Deep Learning)资料 機器學習.深度學習方面不錯的資料,轉載. 原作:https://github.com/ty4z2008 ...
- 【Sprint2 每日Scrum】 第一天(4.22)Sprint2计划会议成果
Sprint2计划会议成果 从今天起我们就开始正式的Sprint2之旅了,经过上一次Sprint1的冲刺计划和几天的调整,我们已经大致了解了敏捷开发的流程和思想,并将我们的TD学生助手做出了大致的框架 ...
- web前端面试系列 - js中的prototype
js中一切皆为对象,其中函数也是一种对象, 而每个函数都有一个prototype属性,其值也是一个对象. 一.prototype的作用 1. 在多个实例对象之间共享数据和方法. 2. 通过原型链实现继 ...