C++ Primer 学习笔记_34_STL实践与分析(8) --引言、pair类型、关联容器

STL实践与分析

--引言、pair类型、关联容器

引言:

关联容器与顺序容器的本质差别在于:关联容器通过键[key]来存储和读取元素,而顺序容器则通过元素在容器中的位置顺序的存取元素。

map的元素以键-值【key-value】对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据。

set仅包括一个键,并有效的支持关于某个键是否存在的查询。


关联容器类型


map


关联数组:元素通过键来存取


Set


大小可变的集合,支持通过键来实现的高速读取


multimap


支持同一个键多次出现的map类型


multiset


支持同一个键多次出现的set类型

一般来说,假设希望有效地存储不同值的集合,那么使用set容器比較合适,而map容器则更适用于须要存储(乃至改动)每一个键所关联的值的情况。

set和map类型的对象不同意为同一个键加入第二个元素。假设一个键必须相应多个实例,则需使用multimap或multiset,这两种类型同意多个元素拥有同样的键。

一、pair类型

pair类型在utility头文件里定义:

	#include <utility>

pair类型提供的操作


pair<T1,T2>p1


创建一个空的pair对象,他的两个元素各自是T1和T2类型,採用值初始化


pair<T1,T2>p1(v1,v2)


创建一个pair对象,它的两个元素各自是T1和T2,当中first成员初始化为v1,而second成员初始化为v2


make_pair(v1,v2)


以v1和v2值创建一个新的pair对象,其元素类型分别为v1和v2的类型


p1<
p2


两个pair对象之间的小于运算,其定义遵循字典次序:假设p1.first<
p2.first 或者!(p2.first<
p1.first) && p1.second < p2.second,则返回true


p1==
p2


假设两个pair对象的first和second成员依次相等,则这两个对象相等。该运算使用其元素的==操作符


p.first


返回p中名为first的(公有)数据成员


p.second


返回p的名为second的(公有)数据成员

1、pair的创建和初始化

在创建pair对象时,必须提供两个类型名:pair对象所包括的两个数据成员各自相应的类型名,这两个类型不必同样:

    pair<string,string> anon;
    pair<string,int> word_count;
    pair<string,vector<int> > line;

能够在定义时为每一个成员提供初始化式:

    pair<string,string> author("James","Joyce");
    cout << "First: " << author.first << endl;
    cout << "Second: " << author.second << endl;

能够利用typedef简化pair的声明:

    typedef pair<string,string> Author;
    Author proust("Marcel","Proust");
    Author joyce("James","Joyce");

2、pair对象的操作

与其它标准库类型不同:对于pair类,能够直接訪问其数据成员,由于其数据成员都是公有的,分别命名为first和second:

    typedef pair<string,string> Author;
    Author author("James","Joyce");

    string firstBook;
    if (author.first == "James" && author.second == "Joyce")
    {
        firstBook = "Stephen Hero";
    }

3、生成新的pair对象

出了构造函数,标准库还定义了make_pair函数,又传递给它的两个实參生成一个新的pair对象:

    pair<string,string> next_auth;
    string first,last;
    while (cin >> first >> last)
    {
        next_auth = make_pair(first,last);
    }

等价于:

        //利用构造函数
        next_auth = pair<string,string>(first,last);

因为pair的数据成员是公有的,所以能够直接的读取输入:

    pair<string,string> next_auth;
    while (cin >> next_auth.first >> next_auth.second)
    {
        //...
    }
//P308 习题10.1
    vector< pair<string,int> > paiVec;

    pair<string,int> paiVal;
    while (cin >> paiVal.first >> paiVal.second)
    {
        paiVec.push_back(paiVal);
    }
	 //习题10.2
    //(1)
    typedef pair<string,int> str_int;
    vector< str_int > paiVec;

    str_int paiVal;
    while (cin >> paiVal.first >> paiVal.second)
    {
        paiVec.push_back(paiVal);
    }
    //2
    vector< pair<string,int> > paiVec;
    string first;
    int second;

    while (cin >> first >> second)
    {
        paiVec.push_back(make_pair(first,second));
    }
    //3
    vector< pair<string,int> > paiVec;
    string first;
    int second;

    while (cin >> first >> second)
    {
        paiVec.push_back(pair<string,int>(first,second));
    }

二、关联容器

1、关联容器共享大部分–
但并非全部的顺序容器的操作:关联容器不支持front、push_front、pop_front、back、pop_back操作。

2、顺序容器和关联容器公共的操作有一下几种:

1)表9.2描写叙述的前三种构造函数:

2)关联容器不能通过容器大小来定义,由于这种话就无法知道键所相应的值是什么。

3)第9.3.4节中描写叙述的关系运算。

4)表9.6列出的begin、end、rbegin和 rend操作。

5)表9.5列出的类型别名(typedef)。注意,对于map容器,value_type并不是元素的类型,而是描写叙述键及其关联值类型的pair类型。

6)表9.11中描写叙述的 swap和赋值操作。但关联容器不提供assign函数。

7)表9.10列出的 clear和 erase操作,但关联容器的erase运算返回 void类型。

8)表9.8列出的关于容器大小的操作。但resize函数不能用于关联容器。

3、依据键排列元素

除了上述列出的操作之外,关联容器还提供了其它的操作。而对于顺序容器也提供的同样操作,关联容器也又一次定义了这些操作的含义或返回类型,当中的区别在于关联容器中使用了键。

“容器元素依据键的次序排列”:在迭代关联容器时,我们能够确保依照键的顺序訪问元素,而与元素在容器中的位置全然无关!

时间: 2024-10-10 12:36:58

C++ Primer 学习笔记_34_STL实践与分析(8) --引言、pair类型、关联容器的相关文章

C++ Primer 学习笔记_45_STL实践与分析(19)--泛型算法的结构

STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用的迭代器类型.比方,假设形參必须为随机訪问迭代器则可提供vector或 deque类型的迭代器,或者提供指向数组的指针.而其它容器的迭代器不能用在这类算法上. C++还提供了另外两种算法模式:一种模式由算法所带的形參定义;还有一种模式则通过两种函数命名和重载的规范定义. 一.算法的形參模式 大多数的

C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法

STL实践与分析 --容器特有的算法 与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作.当中非常大的一个原因就是list容器不是依照内存中的顺序进行布局的,不支持随即訪问,这样,在list容器上就不能使用随即訪问迭代器的算法,如sort等:还有其它的一些算法如:merge.remove.reverse和unique,尽管能够用在list上,但却付出了高昂的性能代价.因此标准库结合list的内部结构,编写出了更快算法: list容器特有的操作

C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)

STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的键相关联,而并不是通过元素在容器中的位置来获取. 一.map对象的定义 1.定义map对象时,必须分别指明键和值的类型: map<string,int> wordCnt; map的构造函数 map<K,V>m; 创建一个名为m的空对象,其键和值的类型分别为K和V map<K,V&

C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】

STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对象将一个值序列写入流中,其操作过程与使用迭代器将一组值逐个赋值给容器中的元素同样: ostream_iterator<string> out_iter(cout,"\n"); istream_iterator<string> in_iter(cin),eof; wh

C++ Primer 学习笔记_29_STL实践与分析(3) --操作步骤集装箱(下一个)

STL实践与分析 --顺序容器的操作(下) 六.訪问元素 假设容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用. [与begin和end的对照:] 1)begin和end返回容器类型的迭代器,而不是引用: 2)end返回容器最后一个元素的下一个位置的迭代器,而back返回容器的最后一个元素的引用! /* *必须保证该list容器非空! *假设容器为空,则if语句内的全部操作都是没有定义的! */ if (!iList.empty()) { list<int>

C++ Primer 学习笔记_41_STL实践与分析(15)--先来看看算法【下一个】

STL实践与分析 --初窥算法[下] 一.写容器元素的算法 一些算法写入元素值.在使用这些算法写元素时一定要当心.必须确保算法所写的序列至少足以存储要写入的元素. 1.写入输入序列的元素 写入到输入序列的算法本质上是安全的--仅仅会写入与指定输入范围数量同样的元素. 写入到输入序列的一个简单算法是fill函数: fill(iVec.begin(),iVec.end(),10); fill(iVec.begin(),iVec.begin()+iVec.size()/2,0); fill带有一对迭代

C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法

STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用的迭代器类型. 比方,假设形參必须为随机訪问迭代器则可提供vector或 deque类型的迭代器,或者提供指向数组的指针. 而其它容器的迭代器不能用在这类算法上. C++还提供了另外两种算法模式:一种模式由算法所带的形參定义;还有一种模式则通过两种函数命名和重载的规范定义. 一.算法的形參模式 大多

C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】

STL实践与分析 --再谈迭代器[下] 三.反向迭代器[续:习题] //P355 习题11.19 int main() { vector<int> iVec; for (vector<int>::size_type index = 0; index != 10; ++index) { iVec.push_back(index); } for (vector<int>::reverse_iterator r_iter = iVec.rbegin(); r_iter !=

C++ Primer 学习笔记_40_STL实践与分析(14)--概要、先来看看算法【上】

STL实践与分析 --概述.初窥算法[上] 标准库容器定义的操作很少.并没有给容器加入大量的功能函数.而是选择提供一组算法,这些算法大都不依赖特定的容器类型,是"泛型"的.可作用在不同类型的容器和不同类型的元素上! 所谓泛型算法:一是由于它们实现共同的操作,所以称之为"算法";而"泛型"指的是它们可以操作在多种容器类型上--不但可作用于vector或list这些标准库类型,还可用在内置数组类型.甚至其它类型的序列上,仅仅要自己定义的容器类型仅仅要