set类型

map 容器是键-值对的集合,好比以人名为键的地址和电话号码。

相反地,set 容器只是单纯的键的集合。
map 适用于字典、电话本、商品价目表等类似的模型。
set 适用于黑名单、白名单等。

// set 容器支持大部分的 map 操作,包括下面几种:

1. 顺序容器和关联容器公共的操作通用的容器操作。

2. 构造函数。(map<k, v> m; map<k, v> m(m2); map<k, v> m(b, e); )

3. nsert 操作。(m.insert(e); m.insert(beg, end); m.insert(iter, e); )

4. count 和 find 操作。(m.count(k); m.find(k); )

5. erase 操作。(m.erase(k); m.erase(p); m.erase(b, e); )

注意两种例外:set 不支持下标操作符,而且没有定义 mapped_type 类型。

在 set 容器中,value_type 是与 key_type 相同的类型。
它们指的都是 set 中存储的元素类型。
这一差别也体现了 set 存储的元素仅仅是键,而没有所关联的值。
与 map 一样,set 容器存储的键也必须唯一,而且不能修改。

[1. set 容器的定义和使用]

为了使用 set 容器,必须包含 set 头文件。set 支持的操作基本上与 map 提供的相同。
与 map 容器一样,set 容器的每个键都只能对应一个元素。
以一段范围的元素初始化 set 对象,或在 set 对象中插入一组元素时,
对于每个键,事实上都只添加了一个元素:

// define a vector with 20 elements, holding two copies of each number from 0 to 9
vector<int> ivec;
for (vector<int>::size_type i = 0; i != 10; ++i) {
  ivec.push_back(i);
  ivec.push_back(i); // duplicate copies of each number
}
// iset holds unique elements from ivec
set<int> iset(ivec.begin(), ivec.end());
cout << ivec.size() << endl; // prints 20
cout << iset.size() << endl; // prints 10

vector 容器,存储 20 个元素:0-9(包括 9)中每个整数都出现了两次。
然后用 ivec 中所有的元素初始化一个 int 型的 set 容器。
这个 set 容器仅有 10 个元素:ivec 中不相同的各个元素。

1.1 在 set 中添加元素
可使用 insert 操作在 set 中添加元素:

set<string> set1;  // empty set
set1.insert("the"); // set1 now has one element
set1.insert("and"); // set1 now has two elements

另一种用法是,调用 insert 函数时,提供一对迭代器实参,插入其标记范围内所有的元素。
该版本的 insert 函数类似于形参为一对迭代器的构造函数——对于一个键,仅插入一个元素:

set<int> iset2;               // empty set
iset2.insert(ivec.begin(), ivec.end()); // iset2 has 10 elements

使用带有一个键参数的 insert 版本返回 pair 类型对象,包含一个迭代器和一个 bool 值,
迭代器指向拥有该键的元素,而 bool 值表明是否添加了元素。
使用迭代器对的 insert 版本返回 void 类型。

1.2 从 set 中获取元素
set 容器不提供下标操作符。为了通过键从 set 中获取元素,可使用 find 运算。
如果只需简单地判断某个元素是否存在,使用 count 运算,返回 set 中该键对应的元素个数。
当然,对于 set 容器,count 的返回值只能是 1(该元素存在)或 0(该元素不存在):

iset.find(1) // returns iterator that refers to the element with key == 1
iset.find(11) // returns iterator == iset.end() iset.count(1) // returns 1
iset.count(11) // returns 0

正如不能修改 map 中元素的键部分一样,set 中的键也为 const。
在获得指向 set 中某元素的迭代器后,只能对其做读操作,而不能做写操作:

// set_it refers to the element with key == 1
set<int>::iterator set_it = iset.find(1);
*set_it = 11; // error: keys in a set are read-only
cout << *set_it << endl; // ok: can read the key

[2. 创建“单词排除”集]

之前的一个程序实现了从 map 对象 word_count 中删除一个指定的单词。
可将这个操作扩展为删除指定文件中所有的单词(即该文件记录的是排除集)。
也即,我们的单词统计程序只对那些不在排除集中的单词进行统计。
使用 set 和 map 容器,可以简单而直接地实现该功能:

 1 void restricted_wc(ifstream &remove_file, map<string, int> &word_count)
2 {
3   set<string> excluded; // set to hold words we'll ignore
4   string remove_word;
5   while (remove_file >> remove_word)
6     excluded.insert(remove_word);
7   // read input and keep a count for words that aren't in the exclusion set
8   string word;
9   while (cin >> word)
10     // increment counter only if the word is not in excluded
11     if (!excluded.count(word))
12       ++word_count[word];
13 }

这个程序类似之前的单词统计程序。其差别在于不需要费力地统计常见的单词。

该函数首先读取传递进来的文件,该文件列出了所有被排除的单词。
读入这些单词并存储在一个名为 excluded 的 set 容器中。
第一个 while 循环完成捍,该 set 对象包含了输入文件中的所有单词。
接下来的程序类似原来的单词统计程序。关键的区别在于:
在统计每个单词之前,先检查该单词是否出现在排除集中。
第二个 while 循环里的 if 语句实现了该功能:

// increment counter only if the word is not in excluded
if (!excluded.count(word))

如果该单词出现在排除集 excluded 中,则调用 count 将返回 1,否则返回 0。
对 count 的返回值做“非”运算,则当该 word 不在 excluded 中时,
条件测试成功,此时修改该单词在 map 中对应的值。
与单词统计程序原来的版本一样,需要使用下标操作符的性质:
如果某键尚未在 map 容器中出现,则将该元素插入容器。
所以第 12 行代码的效果是——
如果 word 还没出现过,则将它插入到 word_count 中,并在插入元素后,将它关联的值初始化为 0。
然后不管是否插入了新元素,相应元素的值都加 1。

set 类型的更多相关文章

  1. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  2. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

  3. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  4. [C#] async 的三大返回类型

    async 的三大返回类型 序 博主简单数了下自己发布过的异步文章,已经断断续续 8 篇了,这次我想以 async 的返回类型为例,单独谈谈. 异步方法具有三个可让开发人员选择的返回类型:Task&l ...

  5. C# - 值类型、引用类型&走出误区,容易错误的说法

    1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...

  6. salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type)

    本篇引用以下三个链接: http://www.tgerm.com/2012/01/recordtype-specific-picklist-values.html?m=1 https://github ...

  7. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  8. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  9. js:给定两个数组,如何判断他们的相对应下标的元素类型是一样的

    题目: 给Array对象原型上添加一个sameStructureAs方法,该方法接收一个任意类型的参数,要求返回当前数组与传入参数数组(假定是)相对应下标的元素类型是否一致. 假设已经写好了Array ...

  10. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

随机推荐

  1. ASP.NET 5是如何通过XRE实现跨平台的

    挡不住的好奇心:ASP.NET 5是如何通过XRE实现跨平台的   .NET程序员也有自己的幸福,.NET的跨平台是一种幸福,.NET的开源也是一种幸福,而更幸福的是可以通过开源的.NET了解.NET ...

  2. 快速构建Windows 8风格应用12-SearchContract概述及原理

    原文:快速构建Windows 8风格应用12-SearchContract概述及原理 本篇博文主要介绍Search Contract概述.Search Contract面板结构剖析.Search Co ...

  3. C++中出现的计算机术语2

    C-style strings(C 风格字符串) C 程序把指向以空字符结束的字符数组的指针视为字符串.在 C++ 中,字符串字面值就是 C 风格字符串.C 标准库定义了一系列处理这样的字符串的库函数 ...

  4. TreeView的绑定

    近期遇到了TreeView的数据库绑定问题,确实是弄了我好几天,特别是多级节点的分步绑定,最開始不分步,发现所有载入页面都卡爆了,真心让人头疼.所以放出来,给须要的朋友看看,以免大家走冤枉路. 1.仅 ...

  5. DDD分层架构之值对象(介绍篇)

    DDD分层架构之值对象(介绍篇) 前面介绍了DDD分层架构的实体,并完成了实体层超类型的开发,同时提供了验证方面的支持.本篇将介绍另一个重要的构造块——值对象,它是聚合中的主要成分. 如果说你已经在使 ...

  6. jquery抖动的按钮

    http://runjs.cn/detail/tyx8dbag //shakenum:抖动的次数,shakeDistance:抖动的距离 jQuery.fn.Shake = function (sha ...

  7. 开源文档管理系统LogicalDOC测试报告---安装篇

    开源文档管理系统LogicalDOC测试报告---安装篇 分类: Linux2011-06-22 15:40 7436人阅读 评论(3) 收藏 举报 文档管理测试mysql数据库installerja ...

  8. 什么是PHP

    PHP(PHP: Hypertext Preprocessor的缩写,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛, ...

  9. Android中的dp,px以及wrap_content的实际展示效果

    因为一个效果中的图片设置了wrap_content的属性,但在720dp跟540dp上面显示不一致使老大非常恼火.跟他讲也讲不明白.于是乎让我们彼此测试来探个究竟.首先测试的是个图片: 它的物理像素是 ...

  10. Kindergarten Counting Game - UVa494

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/uva494.html 题目描述  Kin ...