C++ STL基本容器的使用(vector、list、deque、map、stack、queue)


1、關聯容器和順序容器

  C++中有兩種類型的容器:順序容器和關聯容器,順序容器主要有:vector、list、deque等。關聯容器主要有map和set。如下圖:

1、vector基本使用 

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(vector<T> a)
{
    //輸出方法1
    for(auto i:a)
    {
        cout<<i<<'\t';
    }
    cout<<endl;
    //輸出方法2
    typename vector<T>::iterator it;//前面要加typename,要不會出錯
    for(it=a.begin();it!=a.end();it++)
    {
        cout<<*it<<'\t';
    }
    cout<<endl;
    //輸出方法3,這里只是想說這樣也可以輸出
    cout<<a[0]<<'\t'<<a[1]<<'\t'<<a[2]<<'\t'<<a[3]<<'\t'<<a[4]<<endl;
    cout<<"********************"<<endl;
}

int main()
{
    /*vector初始化對象*/
    vector<int> v1;//v1是一個空的vector,潛在的元素是int類型,執行時,默認初始化
    v1={1,2,3,4,5};
    print(v1);

    vector<int> v2(v1);//相當於vector<int> v2=v1
    print(v2);

    vector<char> v3(5,'a');//v3中含有5個a字符
    print(v3);

    vector<string> v4{"aa","ss","dd","ff","gg"};//v4賦值
    print(v4);

    vector<float> v5(5);//出事化v5,為5個0.0
    v5[0]=1.1;
//    v5[6]=8.8; vector可以利用下標訪問,但是不能使用下標添加元素
    print(v5);

/*-------------------------------------------------------------------------------*/

    /*vector操作*/
    vector<string> v6;
    if(v6.empty())//vector是否為空
    {
        cout<<"------"<<"v6 is empty"<<"-------"<<endl;
    }
    string s="qwe";
    for(int i=0;i<5;i++)
    {
        v6.push_back(s);//末尾添加一個元素
    }
    v6.pop_back();//末尾刪除一個
    v6.push_back("1234");
    print(v6);
    cout<<"------"<<"v6的長度為:"<<v6.size()<<"------"<<endl;
    v6=v4;//拷貝v4中的元素賦值到v6中
    if(v6==v4)
    {
        cout<<"------"<<"v6==v4"<<"------"<<endl;
    }

/*-------------------------------------------------------------------------------*/

    /*vector常用操作*/
    vector<int> array={1,6,2,6,3,6,4,6,5,6};
    array.erase(remove(array.begin(),array.end(),6),array.end());//需添加頭文件algorithm
    /*remove函數使用:
     *remove(始地址,終地址,需要移除的元素),返回是被替換的數第一個數的地址,比如本題vector
     *原始數組為:[1,6,2,6,3,6,4,6,5,6],使用remove函數后為[1,2,3,4,5,6,4,6,5,6],
     *返回的地址為位置5上(0開始)的6的地址,如下輸出數字5.
    cout<<*(remove(array.begin(),array.end(),6)-1)<<endl;*/

    /*刪除6的另一種方法
    vector<int>::iterator it1;
    it1=array.begin();
    for(it1=array.begin();it1!=array.end();it1++)
    {
        if(6==*it1)
        {
            array.erase(it1);//刪除掉it1時,it1會指向下一個數,也就是6,然后再自加會指向下一個6,也就是鄰接的6是刪除不掉的
            it1--;//加上這一句就不會出錯
        }
    }*/
    print(array);

    vector< vector<int> > intVV;//vector實現二維數組
    vector<int> intV;
    int i,j;
    for(i=0;i<3;++i){
        intV.clear();
        for(j=0;j<5;++j)
            intV.push_back(i*10+j);
        intVV.push_back(intV);
    }

    for(i=0;i<3;++i){
        for(j=0;j<5;++j)
            cout<<intVV[i][j]<<'\t';
        cout<<endl;
    }
    return 0;
}
View Code

2、list基本使用

Lst1.assign() 給list賦值 
Lst1.back() 返回最后一個元素 
Lst1.begin() 返回指向第一個元素的迭代器 
Lst1.clear() 刪除所有元素 
Lst1.empty() 如果list是空的則返回true 
Lst1.end() 返回末尾的迭代器 
Lst1.erase() 刪除一個元素 
Lst1.front() 返回第一個元素 
Lst1.insert() 插入一個元素到list中 
Lst1.pop_back() 刪除最后一個元素 
Lst1.pop_front() 刪除第一個元素 
Lst1.push_back() 在list的末尾添加一個元素 
Lst1.push_front() 在list的頭部添加一個元素 
Lst1.rbegin() 返回指向第一個元素的逆向迭代器 
Lst1.remove() 從list刪除元素 
Lst1.rend() 指向list末尾的逆向迭代器 
Lst1.reverse() 把list的元素倒轉 
Lst1.size() 返回list中的元素個數 
Lst1.sort() 給list排序 
Lst1.unique() 刪除list中重復的元素 

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <list>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(list<T> a)
{
    //輸出方法1
    for(auto i:a)
    {
        cout<<i<<'\t';
    }
    cout<<endl;
    //輸出方法2
    typename list<T>::iterator it;//前面要加typename,要不會出錯
    for(it=a.begin();it!=a.end();it++)
    {
        cout<<*it<<'\t';
    }
    cout<<endl;
    cout<<"********************"<<endl;
}

int main()
{
    /*list初始化*/
    list<int> l1;//定義一個空的list
    list<int> l2(5,1);//定以一個長度為5的list
    print(l2);
    list<char> l3={'a','b','c','d'};
    print(l3);
    list<char> l4(l3);//相當於l4=l3
    print(l4);
    list<char> l5(l3.begin(),l3.end());//同上
    print(l5);
    list<char> l6=l5;//同上
    print(l6);

    /*----------------------------------------------------------------------*/

    /*常用操作*/
    list<int> array={6,5,4,3,2,1,7};
    print(array);
    array.sort();
    print(array);
    array.reverse();
    print(array);
    cout<<"返回第一個元素:"<<array.front()<<endl;
    cout<<"返回最后一個元素:"<<array.back()<<endl;
    cout<<"返回第一個元素迭代器:"<<*(array.begin())<<endl;
    cout<<"返回最后一個元素迭代器:"<<*(--array.end())<<endl;
    cout<<"返回第一個元素的逆向迭代器:"<<*(array.rbegin())<<endl;
    cout<<"返回最后一個元素的逆向迭代器:"<<*(array.rend())<<endl;

    list<int> array1;
    array1.assign(array.begin(),array.end());//給list賦值給array1
    array1.pop_front();//刪除第一個元素
    array1.pop_back();//刪除最后一個元素
    print(array1);
    array1.clear();//刪除所有元素
    if(array1.empty())//判斷lsit是否為空
    {
        cout<<"array1 is empty"<<endl;
    }
    array1.assign(6,1);//array1={1,1,1,1,1,1}
    array1.push_front(11);//在list頭插入元素
    array1.push_back(13);//在list尾插入元素
    print(array1);
    array1.erase(array1.begin());//擦除list第一個數
    array1.erase(--array1.end());//擦除list最后一個數
    print(array1);
    cout<<"array1的長度為:"<<array1.size()<<endl;//array1的長度
    array1.insert(++array1.begin(),3,9);//從位置1開始插入3個9
    print(array1);
    array1.remove(9);//移除list中的所有元素9
    print(array1);
    array1.unique();//移除list中重復元素
    print(array1);
    return 0;
}
View Code

 3、deque基本使用

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <deque>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(deque<T> a)
{
    //輸出方法1
    for(auto i:a)
    {
        cout<<i<<'\t';
    }
    cout<<endl;
    //輸出方法2
    typename deque<T>::iterator it;//前面要加typename,要不會出錯
    for(it=a.begin();it!=a.end();it++)
    {
        cout<<*it<<'\t';
    }
    cout<<endl;
    //輸出方法3,這里只是想說這樣也可以輸出
    cout<<a[0]<<'\t'<<a[1]<<'\t'<<a[2]<<'\t'<<a[3]<<'\t'<<a[4]<<endl;
    cout<<"********************"<<endl;
}

int main()
{
    /*deque初始化操作*/
    deque<int> d1(10);
    for(int i=0;i<8;i++)
    {
        d1[i]=i;
    }
    print(d1);
    deque<string> d2(6,"abc");//d2中存在6個abc
    print(d2);
    deque<string> d3(d2);//初始化d3=d2
    print(d3);

    /*----------------------------------------------------------------------*/

    /*deque基本操作*/
    deque<int> array(6,10);
    array.push_front(1);//頭部插入
    array.push_back(2);//尾部插入
    array.insert(array.begin()+1,9);//在位置1插入9
    print(array);
    array.pop_front();//頭部刪除
    array.pop_back();//尾部刪除
    print(array);
    cout<<"頭元素:"<<array.front()<<'\t'<<"尾元素:"<<array.back()<<'\t'<<"大小:"<<array.size()<<endl;
    array.erase(++array.begin(),--array.end());//刪除該區間內的元素
    print(array);
    array.clear();
    if(array.empty())
    {
        cout<<"array is empty"<<endl;
    }
    return 0;

}
View Code

4、set基本使用  

begin()--返回指向第一個元素的迭代器 

clear()--清除所有元素

count()--返回某個值元素的個數

empty()--如果集合為空,返回true 

end()--返回指向最后一個元素的迭代器

equal_range()--返回集合中與給定值相等的上下限的兩個迭代器

erase()--刪除集合中的元素 

find()--返回一個指向被查找到元素的迭代器

get_allocator()--返回集合的分配器

insert()--在集合中插入元素 

lower_bound()--返回指向大於(或等於)某值的第一個元素的迭代器

key_comp()--返回一個用於元素間值比較的函數

max_size()--返回集合能容納的元素的最大限值

rbegin()--返回指向集合中最后一個元素的反向迭代器

rend()--返回指向集合中第一個元素的反向迭代器

size()--集合中元素的數目 

swap()--交換兩個集合變量

upper_bound()--返回大於某個值元素的迭代器

value_comp()--返回一個用於比較元素間的值的函數 

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <set>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(set<T> a)
{
    //輸出方法1
    for(auto i:a)
    {
        cout<<i<<'\t';
    }
    cout<<endl;
    //輸出方法2
    typename set<T>::iterator it;//前面要加typename,要不會出錯
    for(it=a.begin();it!=a.end();it++)
    {
        cout<<*it<<'\t';
    }
    cout<<endl;
    cout<<"********************"<<endl;
}

int main()
{
    /*set初始化操作*/
    set<int> s={11,12,14,15,15};//注意set里面不會存在重復的數
    print(s);
    set<int> s1(s);//s1=s;
    print(s1);

    /*----------------------------------------------------------------------*/

    /*set基本操作*/
    s1.insert(16);//插入一個元素
    int a[]={110,17,18,19};
    s1.insert(a,a+3);//將a的前3個元素插入set
    print(s1);
    cout<<"s1的長度:"<<s1.size()<<'\t'
        <<"s1的第一個元素:"<<*s1.begin()<<'\t'
        <<"s1的最后一個元素:"<<*--s1.end()<<'\t'<<'\n'//注意最后位置要減1
        <<"s1的最后一個元素:"<<*s1.rbegin()<<'\t'
        <<"s1的第一個元素:"<<*--s1.rend()<<'\t'//注意最后位置要減1
        <<endl;

    
    cout<<"s1中11出現的次數是 :"<<s.count(11)<<endl;//因為set保證元素唯一,所以可以判斷數據的存在性
    
    
    cout<<"s1中第一個大於等於17的數是:"<<*s1.lower_bound(17)<<endl;
    cout<<"s1中第一個大於17的數是:"<<*s1.upper_bound(17)<<endl;

    pair<set<int>::const_iterator,set<int>::const_iterator> p;
    p = s.equal_range(14);
    cout<<"第一個大於等於14的數是 :"<<*p.first<<'\t'
        <<"第一個大於14的數是 : "<<*p.second<<endl;


    set<string> s2={"as","ad","af","ag","ah"};
    print(s2);
    s2.erase(s2.begin());//刪除第一個元素
    s2.erase("ad");//刪除對應元素
    print(s2);
    s2.erase(++s2.begin(),--s2.end());//刪除該區間內元素
    print(s2);
    set<string>::iterator iter=s2.find("as");//找到 as 並返回該元素的位置
    cout<<*iter<<endl;
    s2.clear();
    if(s2.empty())
    {
        cout<<"s2 is empty"<<endl;
    }

    return 0;

}
View Code

 5、棧、隊列的使用

棧:

empty() 堆棧為空則返回真

pop() 移除棧頂元素

push() 在棧頂增加元素

size() 返回棧中元素數目

top() 返回棧頂元素 

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <deque>
#include <vector>
#include <list>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(stack<T> a)
{
    while(!a.empty())
    {
        cout<<a.top()<<'\t';
        a.pop();//元素出棧
    }
}

int main()
{
    /*stack的操作*/
    stack<int> s;
    for(int i=0;i<5;i++)
    {
        s.push(i);//元素進棧
    }
    cout<<"s的大小為:"<<s.size()<<endl;
    cout<<"s為:\n";
    print(s);
    cout<<endl;

    deque<int> d(5,7);
    stack<int> s1(d);//將deque賦值給stack
    cout<<"s1為:\n";
    print(s1);
    cout<<endl;

    vector<string> v={"aa","ss","dd","ff"};
    stack<string,vector<string> >s2(v);//將vector賦值給stack
    cout<<"s2為:\n";
    while(!s2.empty())
    {
        cout<<s2.top()<<'\t';
        s2.pop();//元素出棧
    }
    cout<<endl;

    list<char> c={'a','s','d','f','g','h'};
    stack<char,list<char> > s3(c);//將list賦值給stack
    cout<<"s3為:\n";
    while(!s3.empty())
    {
        cout<<s3.top()<<'\t';
        s3.pop();//元素出棧
    }
    cout<<endl;
    return 0;

}
View Code

隊列和棧的基本操作差不多

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <deque>
#include <vector>
#include <list>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(queue<T> a)
{
    while(!a.empty())
    {
        cout<<a.front()<<'\t';
        a.pop();//元素出棧
    }
}

int main()
{
    /*queue的操作*/
    queue<int> s;
    for(int i=0;i<5;i++)
    {
        s.push(i);//元素進棧
    }
    cout<<"s的大小為:"<<s.size()<<endl;
    print(s);
    cout<<endl;

    deque<int> d(5,7);
    queue<int> s1(d);//將deque賦值給stack
    cout<<"s1為:\n";
    print(s1);
    cout<<endl;

    vector<string> v={"aa","ss","dd","ff","hh"};
    queue<string,vector<string> >s2(v);//將vector賦值給stack
    cout<<s2.front()<<'\t'<<s2.back()<<endl;

    list<char> c={'a','s','d','f','g','h'};
    queue<char,list<char> > s3(c);//將list賦值給stack
    cout<<"s3為:\n";
    while(!s3.empty())
    {
        cout<<s3.front()<<'\t';
        s3.pop();//元素出棧
    }
    cout<<endl;
    return 0;

}
View Code

 6、Map的基本使用

Map主要用於資料一對一映射(one-to-one)的情況,map內部的實現自建一顆紅黑樹,這顆樹具有對數據自動排序的功能。

     begin()         返回指向map頭部的迭代器

     clear()        刪除所有元素

     count()         返回指定元素出現的次數

     empty()         如果map為空則返回true

     end()           返回指向map末尾的迭代器

     equal_range()   返回特殊條目的迭代器對

     erase()         刪除一個元素

     find()          查找一個元素

     get_allocator() 返回map的配置器

     insert()        插入元素

     key_comp()      返回比較元素key的函數

     lower_bound()   返回鍵值>=給定元素的第一個位置

     max_size()      返回可以容納的最大元素個數

     rbegin()        返回一個指向map尾部的逆向迭代器

     rend()          返回一個指向map頭部的逆向迭代器

     size()          返回map中元素的個數

     swap()           交換兩個map

     upper_bound()    返回鍵值>給定元素的第一個位置

     value_comp()     返回比較元素value的函數

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <deque>
#include <vector>
#include <list>
using namespace std;

//利用模版進行輸出
template <typename T>
void print(map<T,T> a)
{
    cout<<"輸出的方法1:\n";
    typename map<T, T>::iterator it;
    for(it = a.begin(); it != a.end(); it++)
        cout<<it->first<<' '<<it->second<<endl;
    cout<<"輸出的方法2:\n";
    typename map<T, T>::reverse_iterator iter;
    for(iter = a.rbegin(); iter != a.rend(); iter++)
        cout<<iter->first<<' '<<iter->second<<endl;
}

int main()
{
    /*map的賦值操作*/
    map<string, string> m;
    //賦值的方法1
    m.insert(map<string, string>::value_type ("001", "s1"));
    m.insert(map<string, string>::value_type ("002", "s2"));
    m.insert(map<string, string>::value_type ("003", "s3"));
    //賦值方法2
    m.insert(pair<string,string>("004","s4"));
    m.insert(pair<string,string>("005","s5"));
    m.insert(pair<string,string>("006","s6"));
    print(m);
    cout<<"--------------------------------------------"<<endl;

    map<int, string> m2;
    //賦值的方法3
    m2[1]="one";
    m2[2]="two";
    m2[3]="three";
//    print(m2); 這里兩個類型不一樣不能進行模版輸出
    map<int, string>::iterator iter2;
    for(iter2 = m2.begin(); iter2 != m2.end(); iter2++)
        cout<<iter2->first<<' '<<iter2->second<<endl;
    for(int i=1;i<=3;i++)//這種輸出必須保證map中前一個數為int類型
    {
        cout<<m2[i]<<endl;
    }
    cout<<"--------------------------------------------"<<endl;


    /*判斷插入是否成功*/
    map<char,char> m3;
    m3.insert(map<char,char>::value_type('1','a'));
    m3.insert(map<char,char>::value_type('2','b'));
    m3.insert(map<char,char>::value_type('3','c'));
    m3.insert(map<char,char>::value_type('4','e'));
    m3.insert(map<char,char>::value_type('5','f'));
    m3.insert(map<char,char>::value_type('6','g'));
    pair<map<char,char>::iterator,bool> insert_pair;//接收判斷插入的成功與否

    insert_pair=m3.insert(pair<char,char>('4','d'));
    if(insert_pair.second) cout<<"插入成功!"<<endl;
    else cout<<"插入失敗!"<<endl;

    insert_pair=m3.insert(pair<char,char>('4','d'));
    if(insert_pair.second) cout<<"插入成功!"<<endl;
    else cout<<"插入失敗!"<<endl;
    print(m3);
    cout<<"--------------------------------------------"<<endl;
    cout<<"m3的大小為:"<<m3.size()<<endl;
    cout<<"--------------------------------------------"<<endl;


    /*數據查找*/
    //1
    map<char,char>::iterator iter=m3.find('2');
    if(iter!=m3.end()) cout<<"2對應的值為"<<iter->second<<endl;
    //2
    int n=m3.count('2');
    if(n) cout<<"2存在於map中"<<endl;
    else cout<<"2不存在於map中"<<endl;
    //3
    iter=m3.lower_bound('2');
    cout<<"2對應的值為:"<<iter->second<<endl;
    iter=m3.upper_bound('2');
    cout<<"2后面的鍵對應的值為:"<<iter->second<<endl;
    cout<<"--------------------------------------------"<<endl;


    /*數據刪除*/
    //1
    iter=m3.find('2');
    m3.erase(iter);
    //2
    n=m3.erase('3');
    if(n) cout<<"3以及對應的value刪除成功"<<endl;
    else cout<<"3以及對應的value刪除失敗"<<endl;
    //3
    m3.erase(++m3.begin(),--m3.end());
    print(m3);


}
View Code

 容器選擇的基本原則:

1、除非你有很多的理由選擇其它的容器,否則應該用vector。

2、如果你的程序有很多小的元素,且空間的額外開銷很重要,則不要使用list。

3、如果程序要求隨機訪問元素,則應該使用vector或則deque。

4、如果程序需要在容器的中間插入刪除元素,應該使用list。

5、如果程序需要在容器的頭尾位置插入或刪除元素,但不會在中間位置進行插入或者刪除操作,則使用deque。

6、如果程序只有在讀取輸入時才需要在容器中間位置插入元素,隨后需要隨機訪問元素則:

  首先,確定是否真的需要在容器中間位置添加元素,當處理輸入數據時,通常可以很容易地向vector追加數據,然后調用標准庫的sort函數來重排容器中的元素,從而避免在中間位置添加元素。

  如果必須在中間位置插入元素,考慮在輸入階段使用list,一旦輸入完成,將list中的內容拷貝到一個vector中。

注:如果不確定應該使用哪種容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下表操作,避免隨機訪問。這樣。在必要的時候選擇vector或list都很方便。

 

 

 

 

 


免責聲明!

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



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