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;
}

这里写图片描述

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