C++中常用到的容器


這里主要講C++中經常用到的一些保存數據的容器,其中也會介紹string。

在C++11中提到了很多容器,這里主要介紹:vector、list、map。還有一些其他的容器就不做介紹了。

1.String

  這是我們用得最多的用來表示字符串的類型了 ,下面介紹一下String的一些知識:

  初始化:

  string s1;//這里默認初始化,s1是一個空字符串

  string s2 = s1;//s2是s1的副本,此時s2和s1是里面保存的是一樣的內容

  string s3 = "hiya";//s3是該字符串字面值的副本

  string s3("hiya");//等價於上面的s3

  string s4(10, 'c');//s4的內容是cccccccccc。(10個c)

  string對象上的操作

  os<<s;                  將s寫到輸出流os當中,返回os

  is>>s;                   從is中讀取字符串賦給s,字符串以空白分隔,返回is

  getline(is, s)         從is中讀取一行賦給s,返回is

  s.empty();            s為空返回true,否則返回false

  s.size();                返回s中字符的個數

  s[n];                     返回s中第n個字符的引用,位置從0計起

  s1 + s2;                返回s1和s2連接后的結果

  s1 = s2;                用s2的副本代替s1中原來的字符;

  s1 == s2;           如果s1和s2中所含字符完全一樣,,則它們相等;string對象的相等性判斷對字母的大小寫敏感

  s1 != s2;              

  <,<=,>,>=           利用字符在字典中的順序進行比較,且對字母的大小寫敏感

這里對於string類型的數據,我們可以像訪問數組元素一樣訪問string中的對應字符。

注:還可以使用迭代器來對字符串類型做一些操作,如

  string s("some things");

  if (s.begin() != s.end())

  {

      auto it = s.begin;       //it表示s的第一個字符

      *it = touper(*it);       //將當前字符改為大寫形式

   }

2.vector

   vector類型得到標准定義為:vector<T> v1;其中T為類型,這里可以是內置類型,如int等,也可以是結構體或者類類型。

   初始化

   vector<T> v1;    //v1是一個空的vector,它潛在的元素是T類型,執行默認初始化

   vector<T> v2(v1);  //v2中包含有v1的所有元素的副本

   vector<T> v2 = v1; //等價於v2(v1),v2中包含有v1所有元素的副本

   vector<T> v3(n, val); //v3包含了n個重復的元素,每個元素的值都是val

   vector<T> v4(n); //v4中包含了n個重復執行了值初始化的對象

   vector<T> v5{a,b,c,......}; //v5包含了初始值個數的元素,每個元素被賦予了相應的初始值

   vector<T> v5 = {a,b,c,.......}; //等價於上面的v5

  這里要區分是列表初始化還是值初始化

  vector<int> v1(10);          //v1有10個元素,每個元素的值都是0

  vector<int> v2{10};         //v2有1個元素,該元素的值為10

   vector<int> v3(10,1);      //v3有10個元素,每個元素的值都是1

   vector<int> v4{10,1};     //v4有2個元素,值分別為10和1

  其他操作

  v.empty()                 如果v不返回任何元素,返回真,否則返回假

  v.size()                     返回v中元素的個數

  v.push_back(t)         向v的尾端添加一個值為t的元素

  v[n]                          返回v中第n個位置上的元素的引用,從0開始計起

  v1 = v2;                    用v2中的元素的拷貝替換v1中的元素

  v1 = {a,b,c,......}       用列表中的元素來拷貝替換v1中的元素

  v1 == v2                   v1和v2相等當且僅當它們的元素數量相同且對應位置的元素值都相同

  v1 != v2                    

  <,<=,>,>=                以字典的書序進行比較

 上述介紹的string和vector我們都可以使用基於范圍的for語句來進行范文,如:

  string str("hello");

  for(auto c : str)

   cout << c << endl; 

這里將依次輸出str中的每一個字符,且每一個字符占一行

  vector<string> vec{"hello", “world"};

  for(auto c : vec)

     cout << c << endl;

這里會輸出hello和world,且每個單詞占一行

對於vector我們還可以通過基於范圍的for語句來改變當中的沒一個元素的值

  vector<int> v{1,2,3,4,5,6,7,8,9};

  for(auto &i : v) //對於v中的每一個元素(注意:i是一個引用)

       i *= i;        //求每個元素的平方值

  for(auto i : v)

     cout << i << " ";

 cout << endl;

輸出結果為:1 4 9 16 25 36 49 64 81

注:不能使用下標的形式往vector對象中添加元素

3.list

  這里list和vector基本操作相同,這里就說說它們之間的區別,便於我們選擇用哪一種容器更好,區別如下:

(1)  vector是順序表,表示的是一塊連續的內存,元素被順序存儲;list是雙向連接表,在內存中不一定連續。

 

(2)當數值內存不夠時,vector會重新申請一塊足夠大的連續內存,把原來的數據拷貝到新的內存里面;list因為不用考慮內存的連續,因此新增開銷比vector小。

 

(3)list只能通過指針訪問元素,隨機訪問元素的效率特別低,在需要頻繁隨機存取元素時,使用vector更加合適。

 

(4)當向vector插入或者刪除一個元素時,需要復制移動待插入元素右邊的所有元素;因此在有頻繁插入刪除操作時,使用list更加合適。

下面介紹一個list和vector中的插入。

     vector中可以使用push_back()向容易的尾端插入指定的數據,但是不能使用push_front,該函數是向容器的首端插入指定的元素,這里我們就可以使用insert()函數來實現插入操作,insert包括兩個參數,一個參數是迭代器,用於指出插入元素的位置,這里即使是尾端迭代器也可以,所以insert完成的是向該迭代器所指位置的前一個位置插入指定的元素,如:

  vector<string> vec;

  list<string> lst;

 lst.insert(lst.begin(), "Hello"); //向list類型容器的lst的首端插入”Hello“

 vec.insert(vec.begin(), "Hello"); //同上

 insert除了上述接收兩個參數的形式外,還可以接收三個參數,如:

   vec.insert(vec.begin(), 10, "Hello");  //添加10個Hello字符串到vec的首端

   vector<string> v = {"quasi", "simba", "frollo", "scar"};

   vec.insert(vec.begin(), v.end()-2, v.end()); //將v的最后兩個插入vec的首端

   lst.insert(lst.end(), {"shese", "words", "will", "go”, "at", "the", "end"}); //將后面的列表中的字符串插入lst的尾部

 注:迭代器表示要拷貝的范圍,不能指向與目的位置相同的容器,如:

   lst.insert(lst.begin(), lst.begin(), lst.end());// 這里要插入的迭代器容器是lst,但是要拷貝的范圍也是lst,所以運行時會出現錯誤。

4.map

   map是屬於關聯容器這一類的,包括兩個參數,第一個參數是關鍵字,第二個參數的該關鍵字對應的值。

   對map的一個經典例子是單詞計數器程序:

   map<string, size_t> word_count; //string 到size_t的空map

   string word;

   while(cin >> word)

         ++word_count[word];   //提取word的計數器並將其加1

   for(const auto &w : word_count)   //使用基於范圍的for語句依次訪問map中的數據

        cout << w.first << "occurs" << w.second << ((w.second > 1) ? "times" : "time") << endl;

一般很多時候,我們會將map和set連起來一起用,如下面的例子是改進的上面的單詞計數器的例子,本例子中只統計不在exclude中的單詞

  map<string, size_t> word_count;

  set<string> exclude = {"the", "But", "And", "At", "A", "An"};

  string word;

  while(cin >> word)

      if (exclude.find(word) == exclude.end())

          ++word_count[word];

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM