• 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<<'	';
        }
        cout<<endl;
        //输出方法2
        typename vector<T>::iterator it;//前面要加typename,要不会出错
        for(it=a.begin();it!=a.end();it++)
        {
            cout<<*it<<'	';
        }
        cout<<endl;
        //输出方法3,这里只是想说这样也可以输出
        cout<<a[0]<<'	'<<a[1]<<'	'<<a[2]<<'	'<<a[3]<<'	'<<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]<<'	';
            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<<'	';
        }
        cout<<endl;
        //输出方法2
        typename list<T>::iterator it;//前面要加typename,要不会出错
        for(it=a.begin();it!=a.end();it++)
        {
            cout<<*it<<'	';
        }
        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<<'	';
        }
        cout<<endl;
        //输出方法2
        typename deque<T>::iterator it;//前面要加typename,要不会出错
        for(it=a.begin();it!=a.end();it++)
        {
            cout<<*it<<'	';
        }
        cout<<endl;
        //输出方法3,这里只是想说这样也可以输出
        cout<<a[0]<<'	'<<a[1]<<'	'<<a[2]<<'	'<<a[3]<<'	'<<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()<<'	'<<"尾元素:"<<array.back()<<'	'<<"大小:"<<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<<'	';
        }
        cout<<endl;
        //输出方法2
        typename set<T>::iterator it;//前面要加typename,要不会出错
        for(it=a.begin();it!=a.end();it++)
        {
            cout<<*it<<'	';
        }
        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()<<'	'
            <<"s1的第一个元素:"<<*s1.begin()<<'	'
            <<"s1的最后一个元素:"<<*--s1.end()<<'	'<<'
    '//注意最后位置要减1
            <<"s1的最后一个元素:"<<*s1.rbegin()<<'	'
            <<"s1的第一个元素:"<<*--s1.rend()<<'	'//注意最后位置要减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<<'	'
            <<"第一个大于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()<<'	';
            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为:
    ";
        print(s);
        cout<<endl;
    
        deque<int> d(5,7);
        stack<int> s1(d);//将deque赋值给stack
        cout<<"s1为:
    ";
        print(s1);
        cout<<endl;
    
        vector<string> v={"aa","ss","dd","ff"};
        stack<string,vector<string> >s2(v);//将vector赋值给stack
        cout<<"s2为:
    ";
        while(!s2.empty())
        {
            cout<<s2.top()<<'	';
            s2.pop();//元素出栈
        }
        cout<<endl;
    
        list<char> c={'a','s','d','f','g','h'};
        stack<char,list<char> > s3(c);//将list赋值给stack
        cout<<"s3为:
    ";
        while(!s3.empty())
        {
            cout<<s3.top()<<'	';
            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()<<'	';
            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为:
    ";
        print(s1);
        cout<<endl;
    
        vector<string> v={"aa","ss","dd","ff","hh"};
        queue<string,vector<string> >s2(v);//将vector赋值给stack
        cout<<s2.front()<<'	'<<s2.back()<<endl;
    
        list<char> c={'a','s','d','f','g','h'};
        queue<char,list<char> > s3(c);//将list赋值给stack
        cout<<"s3为:
    ";
        while(!s3.empty())
        {
            cout<<s3.front()<<'	';
            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:
    ";
        typename map<T, T>::iterator it;
        for(it = a.begin(); it != a.end(); it++)
            cout<<it->first<<' '<<it->second<<endl;
        cout<<"输出的方法2:
    ";
        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都很方便。

     

  • 相关阅读:
    [LeetCode] Majority Element II
    [Nginx] 事件模型
    [Nginx] 进程模型
    [C++] 函数中的字符串指针与数组
    [LeetCode] Shortest Distance to a Character
    [LeetCode] Number of Lines To Write String
    Ubuntu 16.04中安装谷歌Chrome浏览器
    Python、机器学习、计算机视觉、深度学习入门
    Sublime安装与配置
    [20160807][系统设计的三次迭代]
  • 原文地址:https://www.cnblogs.com/ybf-yyj/p/9287768.html
Copyright © 2020-2023  润新知