1. 程式人生 > 實用技巧 >primer5:chap09順序容器

primer5:chap09順序容器

chap09、順序容器 291(317/864)

  • 一個容器就是一些特定型別物件的集合。順序容器(sequential container)的順序不依賴於元素的值,而是與元素加入容器時的位置相對應

9.1、順序容器概述

  • 所有順序容器都提供了快速順序訪問元素的能力。但以下方面都有不同的效能折中:
    • 向容器新增或從容器中刪除元素的代價
    • 非順序訪問容器中元素的代價
  • 順序容器型別
    • vector:快速隨機訪問。尾部之外插入/刪除慢
    • deque:快速隨機訪問。頭尾插入/刪除快
    • list:雙向順序訪問。任何位置插入/刪除快
    • forward_list:單向順序訪問。任何位置插入/刪除快
    • array:固定大小,快速隨機訪問,不能新增/刪除元素
    • string:與vector相似,專門用於儲存字元。隨機訪問快。尾部插入/刪除快。
  • 確定使用哪種順序容器
    • 除非你有很好的理由選擇其他容器,否則應使用vector。
    • 如果程式要求隨機訪問元素,應使用vector或deque。
    • 中間插入或刪除元素:list或forward_list
    • 頭尾插入/刪除,但不會在中間插入/刪除,用deque。

9.2、容器庫概覽

  • 0
    • 本節,將介紹對所有容器都適用的操作。
    • 一般來說,每個容器都定義在一個頭檔案中,檔名與型別名相同。容器均定義為模板類
    • list<Sales_data> // 儲存Sales_data物件的list
  • 對容器可以儲存的元素型別的限制
    • vector<vector<string>> lines;//vector的vector
    • 某些類沒有預設建構函式,但在構造這種容器時不能只傳遞給它一個元素數目引數:vector<noDefault> v2(10);//錯誤:必須提供一個元素初始化器 ,比如這樣vector<noDefault> v1(10, init);
    • 表9.2:容器操作,295(321/864)

9.2.1、迭代器

  • 0

    • 迭代器有著公共的介面:
  • 迭代器範圍

    • 左閉合區間 [begin,end) 範圍自begin開始,於end之前結束即不包含end
  • 對構成範圍的迭代器的要求

  • 使用左閉合範圍蘊含的程式設計假定

while(begin != end){
    *begin = val; //正確:範圍非空,因此begin指向一個元素
    ++begin; //移動迭代器,獲取下一個元素
}

9.2.2、容器型別成員

  • 每個容器都定義了多個型別。我們已經使用過其中三種:size_type、iterator、const_iterator
//iter是通過list<string>定義的一個迭代器型別
list<string>::iterator iter;
//count是通過vector<int>定義的一個difference_type型別
vector<int>::difference_type count;

9.2.3、begin和end成員

  • 當我們對一個非常物件呼叫這些成員時,得到的是返回iterator的版本。
  • 只有在對一個const物件呼叫這些函式時,才會得到一個const版本。
  • 當不需要寫訪問時,應使用cbegin和cend。以c開頭的版本是const_iterator的。

9.2.4、容器定義和初始化

  • 0
    • 每個容器型別都定義了一個預設建構函式。除array之外。
    • 表9.3:容器定義和初始化 299(325/864)
  • 將一個容器初始化為另一個容器的拷貝
    • (1)可以直接拷貝整個容器
    • (2)array除外,拷貝由一個迭代器對指定的元素範圍
    • deque<string> authList(authors.begin(),it);//拷貝元素,直到(但不包括)it指向的元素
//每個容器有三個元素,用給定的初始化器進行初始化
list<string> authors = {"Milton","Shakespeare","Austen"};
vector<const char*> articles = {"a","an","the"};

list<string> list2(authors);//正確:型別匹配
deque<string> authList(authors);//錯誤:容器型別不匹配
vector<string> words(articles); //錯誤:容器型別必須匹配

//正確:可以將const char*元素轉換為string
forward_list<string> words(articles.begin(), articles.end());
  • 列表初始化
    • vector<const char*> articles = {"a","an","the"};
  • 與順序容器大小相同的建構函式
vector<int> ivec(10,-1);//10個int元素,每個都初始化為-1
list<string> svec(10,"hi!");//10個strings;每個都初始化為“hi!”
forward_list<int> ivec(10);//10個元素,每個都初始化為0
deque<string> svec(10);//10個元素,每個都是空string
  • 標準庫array具有固定大小

9.2.5、賦值和swap

  • 0
    • 表9.4:容器賦值運算 302(328/864)
  • 使用assgin(僅順序容器)
list<string>names;
vector<const char*> oldstyle;
names = oldstyle;  //錯誤:容器型別不匹配
//正確:可以將const char*轉換為string
names.assign(oldstyle.cbegin(),oldstyle.cend());

//等價於slist1.clear();
//後跟slist1.insert(slist1.begin(),10,"Hiya!");
list<string> slist1(1);//1個元素,為空string
slist1.assign(10,"Hiya!");//10個元素,每個都是"Hiya!"
  • 使用swap

9.2.6、容器大小操作

  • 0
    • size()返回容器中元素的數目
    • empty當size為0時返回布林值true,否則返回false
    • max_size返回一個大於或等於該型別容器所能容納的最大元素數的值

9.2.7、關係運算符

9.3、順序容器操作

9.3.1、向順序容器新增元素

9.3.2、訪問元素

9.3.3、刪除元素

9.3.4、特殊的forward_list

9.3.5、改變容器大小

9.3.6、容器操作可能使迭代器

9.4、vector物件是如何增長的

9.5、額外的string操作

9.5.1、構造string的其他方

9.5.2、改變string的其他方

9.5.3、string搜尋操作

9.5.4、compare函式

9.5.5、數值轉換

9.6、容器介面卡

小結 332(358/864)

履歷

  • 2020-06-03整理了初稿。
  • 2021-01-12開始進行重讀英文版後再進行整理,主要是9.1節。