1. 程式人生 > >從新撿起c++,從stl開始(1)

從新撿起c++,從stl開始(1)

容器包括關聯容器順序容器

關聯容器是通過鍵(key)儲存和讀取元素的,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。

順序容器包括:vector  list  deque等,vector是表示一串連續的記憶體地址,基於陣列實現.   list是不連續的記憶體地址,基於連結串列實現,deque和vector類似,對於首元素提供插入和刪除的雙向支援。

關聯容器:map和set,  map是key-value型別,(redis也是key-value型別,不懂可忽略)。set是單值,map和set的key值唯一。multimap和multiset可以存放多個相同的key值。

vector:

1.可變大小的陣列序列容器。

2.vector也採用的連續儲存空間來儲存元素。也就是意味著可以採用下標對vector的元素進行訪問,和陣列一樣高效。但是又不像陣列,它的大小是可以動態改變的,而且它的大小會被容器自動處理。

3.vector使用動態分配陣列來儲存它的元素。當新元素插入時候,這個陣列需要被重新分配大小為了增加儲存空間。其做法是,分配一個新的陣列,然後將全部元素移到這個陣列。就時間而言,這是一個相對代價高的任務,因為每當一個新的元素加入到容器的時候,vector並不會每次都重新分配大小。

4.vector分配空間策略:vector會分配一些額外的空間以適應可能的增長,因為儲存空間比實際需要的儲存空間更大。不同的庫採用不同的策略權衡空間的使用和重新分配。但是無論如何,重新分配都應該是對數增長的間隔大小,以至於在末尾插入一個元素的時候是在常數時間的複雜度完成的。

5.vector佔用了更多的儲存空間,為了獲得管理儲存空間的能力,並且以一種有效的方式動態增長。

6.與其它動態序列容器相比(deques, lists and forward_lists), vector在訪問元素的時候更加高效,在末尾新增和刪除元素相對高效。對於其它不在末尾的刪除和插入操作,效率更低。比起lists和forward_lists統一的迭代器和引用更好。

#include <vector> //標頭檔案

vector<int> vecInt; //int型別vector 僅宣告

vector<int> vecInt(5);  //定義大小

vector<int> vecInt(5,1); //定義大小為5,初始值都為1


vecInt.size(); //vector的大小
vecInt.max_size(); //最大容量
vecInt.empty(); //是否為空

vecInt.push_back(); //末尾新增元素
vecInt.pop_back(); //彈出最後一個元素

vecInt.begin(); //開始指標
vecInt.end();   //尾部指標
vecInt.cbegin(); //同上,不能通過這個指標修改內容。
vecInt.cend();   //同上

vecInt[index]; //下標訪問
vecInt.at(index); //下標訪問,順便檢查是否越界,越界會丟擲一個錯誤

#include <iostream>
#include <vector>
using namespace std;

void print_vector(vector<int>& val)
{
    cout << "============" << endl;
    vector<int>::iterator it; 
    for(it = val.begin(); it != val.end(); ++it)
    {   
        cout << *it << " ";
    }   
    cout << endl;
}

int main()
{
    vector<int>::iterator it; //迭代器
    vector<int> val;  //vector

    for(int i=0; i<10; i++)
    {
        val.push_back(i); //val新增函式
    }
    
    //列印下上面新增的vector
    /*
    for(it = val.begin(); it != val.end(); it++)
    {
        cout << *it << endl;
    }*/
    
    print_vector(val);
    val.erase(val.begin()+1); // 刪除第一個元素 1 (從0開始計算的)
    print_vector(val);
    val.insert(val.begin()+1, 11); //插入11到原來1的位置上
    print_vector(val);    

    val.erase(val.begin()+2, val.begin()+5); //刪除到val.begin()+5的位置之前。
    print_vector(val);    

    cout << val.size() << endl; //
    cout << val.max_size() << endl;
    
    val.clear(); //清空
    return 0;
}

result:
============
0 1 2 3 4 5 6 7 8 9 
============
0 2 3 4 5 6 7 8 9 
============
0 11 2 3 4 5 6 7 8 9
============
0 11 5 6 7 8 9  
size:7
max_size:4611686018427387903

//一些插入的誤區
vector<int> v;
for(int i=0; i<=10;i++)
{
    v[i] = i; //error,可以這樣讀,但不可以這樣寫入
}

記憶體管理方面:

使用reserve()函式提前設定容量大小,避免多次容量擴充操作導致效率低下。

使用“交換技巧”來修整vector過剩空間/記憶體

用swap方法強行釋放STL Vector所佔記憶體