第9章 顺序容器


9.1 概述
  • 容器种类

    • vector
    • deque 双端队列
    • list 双向链表
    • forward_list 单项链表
    • array 固定大小数组
  • 特性

    • vector、string顺序存储,插入删除较为耗时,但可以随机访问
    • deque支持随机访问,在中间位置插入/删除代价很高,但在两端很快
    • array 比内置数组更加安全
  • 选择容器的基本原则

    • 一般先考虑vector
    • 程序又很多小的元素,且空间的额外开销很重要,则不要使用list、forward_list
    • 要求随机访问则使用vector或者deque
    • 要求在中间插入/删除,使用list、forward_list
    • 只在头尾插入删除,而且不会发生在中间,则使用deque
  • 反向容器 reverse_iterator 不适用于forward_list

  • 类型别名

    • const_iterator 只读取元素,不能修改
    • size_type 足够保存容器的大小
    • value_type 元素类型
    • different_type 两个迭代器之间的距离
    • reference 元素的左值类型=value_type&
    • const_reference
9.2 容器定义和初始化
  • 容器的定义和初始化

    除array外,其他顺序容器的默认构造函数都会创建一个指定类型的容器,且都可以接收大小和初始值参数

    C c(b,e);		//用b,e范围内的元素初始化c
    C c(n,t);		//用n个t初始化c
    
  • 将一个容器初始化为另一个容器的拷贝时,两个容器的类型及其元素类型必须匹配,不过当使用迭代器参数来却低估拷贝范围时,可以不要求容器类型相同,同时元素类型也可不相同,只要能进行类型转换即可

    list<string> authors={"a","b","c"};
    vector<const char*> articles={"the","an","of"};
    
    list<string> list2(authors);		//正确,类型匹配
    deque<string> authList(authors);	//错误,容器类型不匹配
    vector<string> words(articles);		//错误,类型不匹配
    //正确,元素类型可以进行转换
    forward_list<string> words(articles.begin(),articles.end());	
    
  • 列表初始化时,显式地指定了每个元素地值,除array外,初始化列表还隐含了容器地大小

  • array 其大小也是类型的一部分,定义时,应指定其类型和大小,与内置数组不同,array可以进行拷贝和对象赋值

    array<int,10> A={0,1.....,9};
    array<int,10> copy=A;	//正确
    
9.3 容器操作
  • 赋值与swap

    • 赋值

      c1=c2;	//c1所有元素都会被替换为c2的元素,大小也改变为c2的大小
      
    • assign

      仅适用于顺序容器(除array)外,【赋值运算】要求两边具有相同类型。assign允许从一个不相同但相容的类型赋值,或从容器的一个子序列赋值

      list<string> name;
      vector<const char*> old_style;
      name=style;		//错误
      name.assign(old_style.cbegin(),old_style.cend());	//正确
      
    • swap

      两个容器内容交换,除array外,只交换了内部数据结构,并未交换元素本身,调用swap,除string之外的迭代器都不会失效,swap有两个版本,一般使用非成员版本swap(c1,c2)

  • 容器操作

    • insert

      //在给定的迭代器之前插入元素
      slist.insert(slist.begin(),"hello");
      //插入范围内元素
      svect.insert(svect.end(),10,"hello");
      scevt.insert(svect.end(),b,e);	//指定插入内容范围
      

      insert返回 第一个新加入元素的迭代器

    • emplace

      直接构造,而不是拷贝元素

      emplace 将参数传递给元素类型的构造函数
      假设A类型的构造函数,A(int,string);
      c.emplace_back(10,"hello");
      c.push_back(A(10,"hello"));
      
    • 访问元素

      • 所有顺序容器都有front成员函数,除array外都有back成员函数,返回首尾元素的引用
      • 在容器中访问元素的成员函数返回的都是元素的引用,(front,back,下标,at)
      • at 操作会执行是否范围检查,若越界则会报out_of_range异常
      • 删除元素,pop_back()/pop_front()/erase()/clear()返回删除之后位置上的迭代器
  • forward_list的操作

    • 没有定义insert,emplace,erase
    • 定义了特殊的操作,insert_after,emplace_after,erase_after
    • 还定义了首前迭代器before_begin()
  • vector对象的增长

    通常会分配比新的空间需求更大的内存空间,留作后续使用,减少重新分配内存操作

    reserve(n)分配至少n个元素空间,仅影响预先分配多大的内存空间,不改变容器的元素数量

    resize()只改变元素数量,不改变容器的容量

9.4 string的操作
  • substr

    参数为可选的开始位置和数量

    s.substr(pos,n);
    //pos默认值为0,n的默认值为s.size()-pos
    
  • insert和erase

    s.insert(s.size(),5,'A');	//末尾加5个A
    s.erase(s.size(),-5,5);		//删除最后5个字符
    
  • string 搜索

    s.find(args);	//args在s中出现的第一个位置
    s.rfind(args);	//最后一次出现的位置
    s.find_first_of(args);	//s中查找args中任意一个字符第一次出现在s中的位置
    s.find_last_of(args);
    s.find_first_not_of(args);
    s.find_last_not_of(args);
    
    args的构成
    c,pos	字符:c 位置:pos
    s2,pos	串:s2
    cp,pos	指向c风格字符串的指针:cp
    cp,pos,n	从pos位置起,查找cp字符串的前n个字符
    
  • 数值转换

    要转换为数值的string 第一个非空白字符必须是数值中可能出现的字符

    to_string(val);	//val为任意算术类型
    stoi(s,p,b);	//P:保存s中第一个非数值字符下标,默认为0,b:基数,默认为10
    stof(s,p);
    stod(s,p);
    stold(s,p);
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值