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都很方便。

 

 

 

 

 

转载于:https://www.cnblogs.com/ybf-yyj/p/9287768.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值