zoukankan      html  css  js  c++  java
  • 第十六章 string类和标准模板库(2. 标准模板库之容器)

    标准模板库(STL)提供了一组表示容器、迭代器、函数对象和算法的模板。STL不是面向对象的编程,而是一种编程模式——泛型编程。

    面向对象编程关注的是编程的数据方面,而泛型编程关注的是算法。

    容器模板类

    STL具有容器概念和容器类型。概念是一种通用类别(如,基本容器、序列容器、关联容器等);容器类型是可用于创建具体容器对象的模板。

    下面以概念为线索展开

    一、基本容器

    容器概念指定了所有STL容器类都必须满足一系列要求:

    1. 容器是存储其它对象的对象,存储在容器类对象中的对象(内置类型或OOP意义上的对象)必须是同质的。容器类对象过期时,存储在其中的对象也将过期。

    2. 存储在容器类对象中的对象必须是可复制构造的和可赋值的(这些作为元素的对象的类必须定义赋值和复制构造函数)。

    3. 所有容器都提供了某些特征和操作(但基本容器不能保证其元素都按特定的顺序存储,也不能保证元素的顺序不变)。

    二、序列容器

    通过添加要求改进基本容器概念。序列是一种重要改进(满足此概念的容器类型有7种),增加的要求如下(有插入、删除等操作):

    序列的可选要求

    7种容器序列之间的关系:

    vector(计算机矢量)

    vector<string> words(4); //将woords初始化为4个string类型的矢量

    vector提供了自动内存管理功能,模板类型参数指定了使用哪种分配器对象管理内存,默认使用allocator<T>类(T为模板定义的类型),这个类使用new和delete。

    支持随机访问,支持以固定时间在矢量尾插入和删除元素。

    vector是可反转容器概念的模型,此概念有两个类方法:rbegin()和rend()。

    deque(双端队列)

     支持随机访问,并且支持以固定时间在deque对象的开始和末尾插入和删除对象。

    list(双向链表)

    在list对象的任何位置插入和删除元素的时间都是固定的。

    vector强调的是快速访问,而list强调的是快速插入和删除。

    list也是可反转容器概念的模型。

    list不支持数组表示法([ ])和随机访问。

    list模板类中包含双向链表的专用成员函数(未注明的复杂度都为线性):

    ~链表合并:void merge(list<T, Alloc>&x); //合并后x为空

    ~从链表中删除val的所有实例:void remove(const T & val);

    ~使用‘<’运算符对链表进行排序:void sort(); //时间复杂度为NlogN

    ~将链表内容插入到迭代器pos前面:void splice(iterator pos, list<T, Alloc>x); //插入之后x为空

    ~将连续的相同元素压缩为单个元素:void unique();

     queue(队列)

     queue模板类是一个适配器,让底层类(deque)展示典型的队列接口。

    不允许随机访问队列元素,不允许遍历队列。

    queue的使用限制在队列的基本操作上(将元素添加到队尾,从队首删除元素,查看队首和队尾的值,检查元素数目,测试队列是否为空):

     bool empty()const;

    size_type size()const;

    T & front();

    T & back();

    void push(const T & x);

    void pop();

    priority_queue

    是一个适配器类,默认的底层是vector。支持的操作与queue类似,只是默认将最大元素移到队首。

    提供一个可选的构造函数参数:

    priority_queue<int> pd1;

    priority_queue<int> pd2(greater<int>); //greater<int>是一个预定义的用于比较的函数对象

    stack

    是一个适配器类,底层类在默认情况下是vector。

    stack模板的限制比vector多,不支持随机访问和遍历。

    使用限制在使用栈的基本操作上:

    ~查看栈是否为空:bool empty()const;

    ~查看元素数目:sizet_type size();

    ~返回指向栈顶元素的引用:T & top();

    ~在栈顶部插入x:void pop(const T & x);

    ~删除栈顶元素:void pop();

    三、关联容器

    关联容器将值与键关联在一起,是某种树的实现,有比链表更高的访问速度。

    对于关联容器X,X::value_type存储了容器的值类型;X::key_type存储了容器的键类型。

    关联容器允许插入新元素,但不能指定元素位置(因为关联容器有确定元素访问位置的算法)。

    set / multiset

    存储在头文件set中,键与值相同,multiset允许集合中存在相同的值。

    set模拟了关联、反转、排序、键唯一的概念。

    set的第二个模板参数是可选的,指示用来对键进行排序的比较函数或对象(默认使用模板less<>)。

    set也有一个将迭代器区间作为参数的构造函数。

     集合的标准操作:

    ~注:以下这些函数并不是方法而是通用函数,使用这些函数的先决条件是容器必须是经过排序的,set对象自动满足这一条件。

    ~并集:1. set_union(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator< string, char > out(cout, " ") ); //最后一个参数是输出迭代器

         2. set_union(A.begin(), A.end(), B.begin(), B.end(), insert_iterator< set<string> > ( C, C.begin() ) ); //将并集插入到C.begin()指示的位置处

    ~交集:set_intersection();

    ~差集:set_difference();

    ~以下为set的方法

    ~lower_bound(); //将键作为参数,返回指向第一个不小于键参数的迭代器;

    ~upper_bound(); //将键作为参数,返回指向第一个大于键参数的迭代器。

    map / multimap

    map是反转和排序的概念模型,但键和值的类型不同。multimap的同一个键可以与多个值关联。

    创建multimap对象:

    multimap<int, string> codes; //也有第三个可选参数,用于指出对键进行排序的比较函数或对象

    STL模板类pair<class T, class U>将键和值存储在一个对象中:

    pair<const int, string> item(213, "Los");

    code.insert(item); //因为数据是按键排序的,所以不需要指出插入位置。

    对于pair对象,可以使用first和second成员来访问其两个部分:

    item.first; //返回键

    item.second; //返回值

    获取multimap对象的信息:

    ~将键作为参数,返回该键元素的数目:count();

    ~lower_bound; upper_bound(); //与set相同

    ~将键作为区间,返回该键所在迭代器区间:equal_range(); //返回的值封装在一个pair对象中,这里的pair模板两个类型参数都是multimap迭代器。

    pair< multimap<int string>::iterator, multimap<int string>::iterator > range = code.equal_range(718);

  • 相关阅读:
    canvas绘制折线路径动画
    canvas绘制虚线图表
    BootstrapTable 行内编辑解决方案:bootstrap-table-editor
    canvas绘制图像轮廓效果
    三维场景中常用的路径动画
    三维组态部件动画解决方案
    canvas多重阴影发光效果
    萌新的算法课-方法论
    网易云ncm文件转换器
    PyCharm永久激活
  • 原文地址:https://www.cnblogs.com/sungnox/p/7701797.html
Copyright © 2011-2022 走看看