STL基本容器的使用

聲明:
本文綜合
http://blog.csdn.net/conanswp/article/details/23297441
http://www.cnblogs.com/LonelyEnvoy/p/5850679.html
http://blog.csdn.net/bingxuebage/article/details/5729064
而編輯。

1.基本容器介紹

C++中有兩種類型的容器:順序容器和關聯容器。順序容器主要有vector、list、deque等。其中vector表示一段連續的內存,基於數組實現,list表示非連續的內存,基於鏈表實現,deque與vector類似,但是對首元素提供插入和刪除的雙向支持。關聯容器主要有map和set。map是key-value形式,set是單值。map和set只能存放唯一的key,multimap和multiset可以存放多個相同的key。
容器類自動申請和釋放內存,因此無需new和delete操作。
通常使用步驟如下:

大致有下面6個步驟:
1.添加相應的頭文件(如 #include <list> )( 注意,沒有 .h )
2.添加std命名空間(用 using namespace std; )
3.賦予模板具體的使用類型(如 typedef list<string> LISTSTR; )
4.實例化模板(如 LISTSTR test; )
5.實例化遊標(如 LISTSTR::iterator i; )
6.通過迭代器對象訪問模板對象,例如
// 逐個輸出鏈表test中的元素
for ( i =  test.begin(); i != test.end(); ++i )
     cout << *i << " ";

容器模板中常用的函數有:

assign()           //賦值
empty()            //容器爲空則返回非0值
erase()            //刪除指定位置或指定範圍內的元素
push_front()   //從容器頭部插入元素  
push_back()   //從容器尾部插入元素
pop_front()     //刪除第一個元素
pop_back()    // 刪除最後一個元素
back()              //返回最後一個元素的引用
front()              //返回第一個元素的引用
begin()             //返回指向第一個元素的遊標 (與迭代器配合使用)
end()                //返回指向最後一個元素的後一個位置的遊標 (最後1個元素再加1) (與迭代器配合使用)

1.1 vector

vector基於模板實現,需包含頭文件vector。

1.1.1 定義和初始化


    //1.定義和初始化
    vector<int> vec1;    //默認初始化,vec1爲空
    vector<int> vec2(vec1);  //使用vec1初始化vec2
    vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2,效果同上
    vector<int> vec4(10);    //10個值爲0的元素
    vector<int> vec5(10,4);  //10個值爲4的元素

1.1.2 常用方法

    vec1.push_back(100);            //添加元素
    int size = vec1.size();         //元素個數
    bool isEmpty = vec1.empty();    //判斷是否爲空
    cout<<vec1[0]<<endl;        //取得第一個元素
    vec1.insert(vec1.end(),5,3);    //從vec1.back位置插入個值爲的元素
    vec1.pop_back();              //刪除末尾元素
    vec1.erase(vec1.begin(),vec1.end());//刪除之間的元素,其他元素前移
    cout<<(vec1==vec2)?true:false;  //判斷是否相等==、!=、>=、<=...
    vector<int>::iterator iter = vec1.begin();    //獲取迭代器首地址
    vector<int>::const_iterator c_iter = vec1.begin();   //獲取const類型迭代器
    vec1.clear();                 //清空元素

1.1.3 遍歷

    //下標法
    int length = vec1.size();
    for(int i=0;i<length;i++)
    {
       cout<<vec1[i];
    }
    cout<<endl<<endl;

    //迭代器法
    vector<int>::const_iterator iterator = vec1.begin();
    for(;iterator != vec1.end();iterator++)
    {
       cout<<*iterator;
    }

1.1.4 例程

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

int ar[10] = { 12, 45, 234, 64, 12, 35, 63, 23, 12, 55 };
char* str = "Hello World";

int main()
{
    vector <int> vec1(ar, ar + 10);   //first=ar,last=ar+10,不包括ar+10  
    vector < char > vec2(str, str + strlen(str)); //first=str,last= str+strlen(str),  

    //打印vec1和vec2,const_iterator是迭代器,後面會講到  
    //size()是vector的一個成員函數  
        cout << "vec1:" << endl;
        cout << "size is "<<vec1.size() << endl;
/*      for (int i=0; i<vec1.size(); i++)cout << vec1[i];*/
/*      這種方式也可以*/
    for (vector<int>::const_iterator p = vec1.begin(); p != vec1.end(); p++)
        cout << *p<<"  ";
        cout << endl;

        cout << "size is " << vec2.size() << endl;
        cout <<"vec2:" << endl;
    for (vector< char >::const_iterator p1 = vec2.begin(); p1 != vec2.end(); p1++)
        cout << *p1;
        cout << endl;
    return 0;
}

這裏寫圖片描述
爲了幫助理解向量的概念,這裏寫了一個小例子,其中用到了vector的成員函數:begin(),end(),push_back(),assign(),front(),back(),erase(),empty(),at(),size()。

#include <iostream>  
#include <vector>  
using namespace std;
//使用typedef自定義類型INTVECTOR
typedef vector<int> INTVECTOR;  
//測試vector容器的功能  
int main()
{
    //vec1對象初始爲空  
    INTVECTOR vec1;
    //vec2對象最初有10個值爲6的元素    
    INTVECTOR vec2(10, 6);
    //vec3對象最初有3個值爲6的元素,拷貝構造  
    INTVECTOR vec3(vec2.begin(), vec2.begin() + 3);
    //聲明一個名爲i的雙向迭代器  
    INTVECTOR::iterator i;
    //從前向後顯示vec1中的數據  
    cout << "vec1.begin()--vec1.end():" << endl;
    for (i = vec1.begin(); i != vec1.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //從前向後顯示vec2中的數據  
    cout << "vec2.begin()--vec2.end():" << endl;
    for (i = vec2.begin(); i != vec2.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //從前向後顯示vec3中的數據  
    cout << "vec3.begin()--vec3.end():" << endl;
    for (i = vec3.begin(); i != vec3.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //測試添加和插入成員函數,vector不支持從前插入  
    vec1.push_back(2);//從後面添加一個成員  
    vec1.push_back(4);
    vec1.insert(vec1.begin() + 1, 5);//在vec1第一個的位置(vec1[1])上插入成員5  
    //從vec1第一的位置開始插入vec3的所有成員  
    vec1.insert(vec1.begin() + 1, vec3.begin(), vec3.end());
    cout << "after push() and insert() now the vec1 is:" << endl;
    for (i = vec1.begin(); i != vec1.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //測試賦值成員函數  
    vec2.assign(8, 1);   // 重新給vec2賦值,8個成員的初始值都爲1  
    cout << "vec2.assign(8,1):" << endl;
    for (i = vec2.begin(); i != vec2.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //測試引用類函數  
    cout << "vec1.front()=" << vec1.front() << endl;//vec1第零個成員  
    cout << "vec1.back()=" << vec1.back() << endl;//vec1的最後一個成員  
    cout << "vec1.at(4)=" << vec1.at(4) << endl;//vec1的第五個成員  
    cout << "vec1[4]=" << vec1[4] << endl;
    //測試移出和刪除  
    vec1.pop_back();//將最後一個成員移出vec1  
    vec1.erase(vec1.begin() + 1, vec1.end() - 2);//刪除成員,減幾後邊留幾個  
    cout << "vec1.pop_back() and vec1.erase():" << endl;
    for (i = vec1.begin(); i != vec1.end(); ++i)
        cout << *i << " ";
    cout << endl;
    //顯示序列的狀態信息  
    cout << "vec1.size(): " << vec1.size() << endl;//打印成員個數  
    cout << "vec1.empty(): " << vec1.empty() << endl;//清空  
}

這裏寫圖片描述

1.2 deque

deque容器類與vector類似,支持隨機訪問和快速插入刪除,它在容器中某一位置上的操作所花費的是線性時間。與vector不同的是,deque還支持從開始端插入數據:push_front()。其餘類似vector操作方法的使用。
此外deque也不支持與vector的capacity()、reserve()類似的操作。

1.2.1 例程

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

typedef deque<int> INTDEQUE;//用typedef定義  

//從前向後顯示deque隊列的全部元素的子函數
void put_deque(INTDEQUE deque, char *name)
{
    INTDEQUE::iterator pdeque;//定義遊標  
    cout << "The contents of " << name << " : ";
    for (pdeque = deque.begin(); pdeque != deque.end(); pdeque++)
        cout << *pdeque << " ";//注意有 "*"號哦,沒有"*"號的話會報錯  
    cout << endl;
}

//測試deqtor容器的功能  
int main()
{
    //deq1對象初始爲空  
    INTDEQUE deq1;
    //deq2對象最初有10個值爲6的元素    
    INTDEQUE deq2(10, 6);
    //聲明一個名爲i的雙向迭代器變量  
    INTDEQUE::iterator i;
    //從前向後顯示deq1中的數據  
    put_deque(deq1, "deq1");
    //從前向後顯示deq2中的數據  
    put_deque(deq2, "deq2");
    //從deq1序列後面添加兩個元素  
    deq1.push_back(2);
    deq1.push_back(4);
    cout << "deq1.push_back(2) and deq1.push_back(4):" << endl;
    put_deque(deq1, "deq1");
    //從deq1序列前面添加兩個元素  
    deq1.push_front(5);
    deq1.push_front(7);
    cout << "deq1.push_front(5) and deq1.push_front(7):" << endl;
    put_deque(deq1, "deq1");
    //在deq1序列中間插入數據  
    deq1.insert(deq1.begin() + 1, 3, 9);
    cout << "deq1.insert(deq1.begin()+1,3,9):" << endl;
    put_deque(deq1, "deq1");
    //測試引用類函數  
    cout << "deq1.at(4)=" << deq1.at(4) << endl;
    cout << "deq1[4]=" << deq1[4] << endl;
    deq1.at(1) = 10;
    deq1[2] = 12;
    cout << "deq1.at(1)=10 and deq1[2]=12 :" << endl;
    put_deque(deq1, "deq1");
    //從deq1序列的前後各移去一個元素  
    deq1.pop_front();
    deq1.pop_back();
    cout << "deq1.pop_front() and deq1.pop_back():" << endl;
    put_deque(deq1, "deq1");
    //清除deq1中的第2個元素  
    deq1.erase(deq1.begin() + 1);
    cout << "deq1.erase(deq1.begin()+1):" << endl;
    put_deque(deq1, "deq1");
    //對deq2賦值並顯示  
    deq2.assign(8, 1);
    cout << "deq2.assign(8,1):" << endl;
    put_deque(deq2, "deq2");
    return 0;
}

1.3 list

List是stl實現的雙向鏈表,與 向量(vectors)相比, 它允許快速的插入和刪除,但是隨機訪問卻比較慢。需要添加頭文件list。
只能順序訪問(從前向後或者從後向前)。與前面兩種容器類有一個明顯的區別就是:它不支持隨機訪問。要訪問表中某個下標處的項需要從表頭或表尾處(接近該下標的一端)開始循環。而且缺少下標預算符:operator[]。

1.3.1 定義和初始化

定義和初始化
    list<int> lst1;          //創建空list
    list<int> lst2(3);       //創建含有三個元素的list
    list<int> lst3(3,2); //創建含有三個元素的list
    list<int> lst4(lst2);    //使用lst2初始化lst4
    list<int> lst5(lst2.begin(),lst2.end());  //同lst4

1.3.2 常用操作方法

常用操作方法
    lst1.assign(lst2.begin(),lst2.end());  //分配值
    lst1.push_back(10);                    //添加值
    lst1.pop_back();                   //刪除末尾值
    lst1.begin();                      //返回首值的迭代器
    lst1.end();                            //返回尾值的迭代器
    lst1.clear();                      //清空值
    bool isEmpty1 = lst1.empty();          //判斷爲空
    lst1.erase(lst1.begin(),lst1.end());                        //刪除元素
    lst1.front();                      //返回第一個元素的引用
    lst1.back();                       //返回最後一個元素的引用
    lst1.insert(lst1.begin(),3,2);         //從指定位置插入個
    lst1.rbegin();                         //返回第一個元素的前向指針
    lst1.remove(2);                        //相同的元素全部刪除
    lst1.reverse();                        //反轉
    lst1.size();                       //含有元素個數
    lst1.sort();                       //排序
    lst1.unique();                         //刪除相鄰重複元素

1.3.3 遍歷

和前兩個類似

   //迭代器法
    for(list<int>::const_iterator iter = lst1.begin();iter != lst1.end();iter++)
    {
       cout<<*iter;
    }
    cout<<endl;

1.3.4 例程

merge函數的作用是:將兩個有序的序列合併爲一個有序的序列。函數參數
merge(first1,last1,first2,last2,result,compare)
firs1t爲第一個容器的首迭代器,last1爲第一個容器的末迭代器,first2爲第二個容器的首迭代器,last2爲容器的末迭代器,result爲存放結果的容器,comapre爲比較函數(可略寫,默認爲合併爲一個升序序列)。

#include <iostream>  
#include <string>  
#include <list>  
using namespace std;

void PrintIt(list<int> n)
{
    for (list<int>::iterator iter = n.begin(); iter != n.end(); ++iter)
        cout << *iter << " ";//用迭代器進行輸出循環  
}

int main()
{
    list<int> listn1, listn2;    //給listn1,listn2初始化  
    listn1.push_back(123);
    listn1.push_back(0);
    listn1.push_back(34);
    listn1.push_back(1123);    //now listn1:123,0,34,1123  
    listn2.push_back(100);
    listn2.push_back(12);    //now listn2:12,100  
    listn1.sort();
    listn2.sort();    //給listn1和listn2排序  
    //now listn1:0,34,123,1123         listn2:12,100  
    cout << "listn1 is "<<endl;
    PrintIt(listn1);
    cout << endl;
    cout << "listn2 is "<<endl;
    PrintIt(listn2);
    cout << endl;
    cout << "after merge is " << endl;
    listn1.merge(listn2);    //合併兩個排序列表後,listn1:0,12,34,100,123,1123  
    PrintIt(listn1);
    cout << endl;
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章