1. 程式人生 > 其它 >理解:STL

理解:STL

技術標籤:C/C++程式設計c++stl

文章目錄

總覽

參考連線

STL是std的子集

  • STL(Standard Template Library),即標準模板庫
  • STL的一個重要特點是資料結構和演算法的分離。例如,由於STL的sort()函式是完全通用的,你可以用它來操作幾乎任何資料集合,包括連結串列,容器和陣列;
  • STL另一個重要特性是它不是面向物件的。為了具有足夠通用性,STL主要依賴於模板

STL中六大元件:

  1. 容器(Container),是一種資料結構,如list,vector,和deques ,以模板類的方法提供。為了訪問容器中的資料,可以使用由容器類輸出的迭代器;

  2. 迭代器(Iterator),提供了訪問容器中物件的方法。例如,可以使用一對迭代器指定list或vector中的一定範圍的物件。迭代器就如同一個指標。事實上,C++的指標也是一種迭代器。但是,迭代器也可以是那些定義了operator*()以及其他類似於指標的操作符地方法的類物件;

  3. 演算法(Algorithm),是用來操作容器中的資料的模板函式。例如,STL用sort()來對一個vector中的資料進行排序,用find()來搜尋一個list中的物件,函式本身與他們操作的資料的結構和型別無關,因此他們可以在從簡單陣列到高度複雜容器的任何資料結構上使用;

  4. 仿函式(Functor)

  5. 介面卡(Adaptor)

  6. 分配器(allocator)

容器

序列式容器:Vector;Deque;List;

關聯式容器:Map/Multimap; Set/Multiset

理解:vector

動態陣列

List是stl實現的雙向連結串列,與向量(vectors)相比, 它允許快速的插入和刪除,但是隨機訪問卻比較慢.

**List不支援隨機訪問,因此訪問元素的效率較低,**list沒有at和下標運算子

push_back &pop_back:在容器最後新增和刪除

#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>//sort演算法包含
using namespace std;
int main()
{
    vector<int>obj;//建立一個向量儲存容器 int
    /**********push_back*****/
    for(int i=0;i<10;i++) // push_back(elem)在陣列最後新增資料
    {
        obj.push_back(i);
        cout<<obj[i]<<",";    
    }
    cout<<endl;
    /**********pop_back*****/
    for(int i=0;i<5;i++)//去掉陣列最後一個數據
    {
        obj.pop_back();
    }
    for(int i=0;i<obj.size();i++)//size()容器中實際資料個數
    {
        cout<<obj[i]<<",";
    }
    cout<<endl;
    /**********sort&reverse*****/
    obj.push_back(100);obj.push_back(-9);obj.push_back(20);
    sort(obj.begin(),obj.end());//預設升序,也可以改變sort的定義如:sort(begin,end,compare)
    vector<int>::iterator iter;
    reverse(obj.begin(),obj.end());//只是改變方向,它不是排序
    for(iter=obj.begin();iter!=obj.end();iter++)
    {
        cout<<*iter<<",";
    }
    cout<<endl;
    /****at形式訪問*******/
    cout<<obj.at(2)<<endl;//at形式訪問
    obj.clear();//清空
    cout<<"size:"<<obj.size();//size為0;
    return 0;
}

理解:List

參考連線

理解:Map

C++中map提供的是一種鍵值對容器,裡面的資料都是成對出現的,如下圖:每一對中的第一個值稱之為關鍵字(key),每個關鍵字只能在map中出現一次;第二個稱之為該關鍵字的對應值。

map內部自建一顆紅黑樹(一 種非嚴格意義上的平衡二叉樹),這顆樹具有對資料自動排序的功能,所以在map內部所有的資料都是有序的

map和multimap都需要#include,唯一的不同是,map的鍵值key不可重複,而multimap可以,也正是由於這種區別,map支援[ ]運算子,multimap不支援[ ]運算子。在用法上沒什麼區別。


pair

也在std中(vector,list,map也在std中),但是在map中有應用,所以先講一下。

參考連線

其標準庫型別–pair型別定義在#include 標頭檔案中,定義如下:

好像utility和iostream都可以,這是為什麼呢???

類模板:template<class T1,class T2> struct pair

引數:T1是第一個值的資料型別,T2是第二個值的資料型別。

功能:pair將一對值(T1和T2)組合成一個值,這一對值可以具有不同的資料型別(T1和T2), 兩個值可以分別用pair的兩個公有函式first和second訪問。

定義建構函式

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; // 如果兩個物件的first和second依次相等,則這兩個物件相等;該運算使用元素的==操作符。

p1.first; // 返回物件p1中名為first的公有資料成員

p1.second; // 返回物件p1中名為second的公有資料成員

例如:

pair<string, string> anon; // 建立一個空物件anon,兩個元素型別都是string
pair<string, int> word_count; // 建立一個空物件 word_count, 兩個元素型別分別是string和int型別
pair<string, vector<int> > line; // 建立一個空物件line,兩個元素型別分別是string和vector型別
//下面是定義的時候初始化
pair<string, string> author("James","Joy"); // 建立一個author物件,兩個元素型別分別為string型別,並預設初始值為James和Joy。
pair<string, int> name_age("Tom", 18);

程式碼:

tie參考連線

#include<iostream>
#include <tuple>//用於包含tie,std:Ltie
using namespace std;
//std::pair  std::tie
std::pair<std::string, int> getPreson() {
    return std::make_pair("Sven", 25);
}//這個是函式,返回值為pair型別
int main()
{
    /********訪問***************/
    pair<int ,double> p1;
    p1.first = 1;
    p1.second = 2.5;
    cout<<p1.first<<' '<<p1.second<<endl;
    /*****利用make_pair建立新的pair物件**/
    pair<int, double> p3;
    p3 = make_pair(1, 1.2);
    cout << p3.first << p3.second << endl;
    /*****通過std::tie獲取pair元素值***/
    string name;
    int ages;
    tie(name, ages) = getPreson();
    cout << "name: " << name << ", ages: " << ages << endl;
}

map

map中的元素是自動按Key升序排序,所以不能對map用sort函式;

程式碼理解:

#include <map>    
#include <string>  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    map<int, string> mapStudent =
    {
        {0,"student_zero"}
    }; //初始化
    std::pair<map<int, string>::iterator, bool> ret;
    
    mapStudent[1] = "student_one";//陣列插入
    ret = mapStudent.insert(pair<int, string>(1, "student_two")); //pair插入,並返回是否插入成功
    mapStudent.insert(map<int, string>::value_type (2, "student_two"));//value_type插入
    map<int, string>::iterator iter;  //迭代器訪問
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       cout<<iter->first<<' '<<iter->second<<endl;  
    
    if(!mapStudent.empty())
    {
        cout<<"size:"<<mapStudent.size()<<endl;//map的大小
        cout<<"max_size:"<<mapStudent.max_size()<<endl;//最多存多少,和記憶體有關?
        cout<<"map count"<<mapStudent.count(3)<<endl;//查詢key的value個數,map非0即1
    }
    /********find*****/
    iter = mapStudent.find(1);
    cout<<"find num 1:"<<iter->second<<endl;
    /*****erase*****/
    map<int, string>::iterator iter_1;  //迭代器訪問
    iter_1 = mapStudent.erase(iter);
    cout<<"iter:"<<iter->second<<endl;//原來的迭代器還在指向
    cout<<"num 1:"<<iter_1->second<<endl<<endl;
    
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       cout<<iter->first<<' '<<iter->second<<endl;
}