C++STL标准库学习笔记(十)vector deque list

本文通过示例介绍了 C++ STL 中 vector、deque 和 list 容器的基本使用方法及特性,包括一维和二维数组的实现、常用操作如 insert 和 erase 的应用,以及 deque 和 list 的特有功能。

目录

前言:

正文:

1. vector示例程序

2. 用vector实现二维数组

3. deque

4. list容器

后记:


前言:

        在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来。

        在这一篇文章中,我们主要对vector deque list进行简单的介绍,(真的很简单的介绍,如果想要知道所有函数的用法的话,建议去看一下其他人的总结,我这里主要是记录一个学习过程,提供一个学习思路)

        因为它们的操作大多相同,就不一个个列举它们的操作了,一个优秀的IDE能自动提示“.”后面应该接什么,函数里面应该填什么,反复强调已经了解过的知识就有点冗杂了。

正文:

1. vector示例程序

#include<iostream>
#include<vector>
using namespace std;
template<class T>
void PrintVector(T s, T e)
{
    for (; s != e; s++)
    {
        cout<<* s<<" ";
    }
    cout<<endl;
}

int main(int argc, char const *argv[])
{
    int a[5] = {1,2,3,4,5};
    vector<int> v(a,a+5);
    //用数组来构造vector
    cout<<"1)"<<v.end() - v.begin()<<endl;//结果:1)5
    cout<<"2)";
    PrintVector(v.begin(),v.end());//结果:2)1 2 3 4 5
    v.insert(v.begin() + 2, 13);
    //在第二个元素后面插入元素
    cout<<"3)";
    PrintVector(v.begin(),v.end());//结果:3)1 2 13 3 4 5
    v.erase(v.begin() + 2);
    //删除迭代器指向的元素
    cout<<"4)";
    PrintVector(v.begin(),v.end());//结果:4)1 2 3 4 5
    vector<int> v2(4,100);
    //构造函数,创造四个元素值为100的vector
    v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);//将v的一段插入v2的开头
    cout<<"5) v2:";
    PrintVector(v2.begin(),v2.end());//结果:5) v2:2 3 100 100 100 100
    v2.erase(v.begin()+1, v.begin()+3);
    //删除了v的一个区间,即2,3
    cout<<"6)";
    PrintVector(v.begin(),v.end());//结果:6)1 4 5
    return 0;
}

        老样子,找出其中重要的部分来细锁。

                int a[5] = {1,2,3,4,5};

                vector<int> v(a,a+5);

        这里是建立了一个int数组,然后用这个数组来创造一个vector。

                v.end() - v.begin()

        这个在这个程序中的结果是5,说明vector的迭代器是随机访问迭代器,毕竟只有它才能实现加减操作。

                v.insert(v.begin() + 2, 13);

        在第二个元素后面插入13(不就是在下标2插入元素然后后面的元素集体后移吗),没什么需要特别强调的。

                v.erase(v.begin() + 2);

        删除第二个元素后面(不就是下标为2的元素吗)的元素。

                vector<int> v2(4,100);

        构造函数,v2包含四个值为100的元素。(充分体现了STL标准库的聪明机智,直接省去麻烦的一个个赋值)

                v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);

        在v2的开头插入v的下标为1到下标为2(1和3的左闭右开区间)的元素。(STL标准库普遍如此)

                v2.erase(v.begin()+1, v.begin()+3);

        擦去下标为1和2的元素([1,3)的元素)

2. 用vector实现二维数组

样例:

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

int main(int argc, char const *argv[])
{
    vector<vector<int>>v(3);
    //v有3个元素,每个元素都是vector<int>容器
    for (int i = 0; i < v.size(); i++)
    {
        for (int j = 0; j < 4; j++)
        {
            v[i].push_back(j);
        }
    }
    for (int i = 0; i < v.size(); i++)  
    {
        for (int j = 0; j < 4; j++)
        {
            cout<<v[i][j]<<" ";
        }
        cout<<endl;
    }
    /*
    结果:
    0 1 2 3
    0 1 2 3
    0 1 2 3
    */
    return 0;
}

        从本质上来看,就是套娃,但是它的元素可以通过v[i][j]来调用,可以说是非常方便的

        注意:

                vector<vector<int> >v(3);

        在定义时,里面的vector<int>后面要记得跟一个空格,部分编译器可能会把两个“>”号看成右移运算符

3. deque

        双向队列

        所有适用于vector的操作都适用于deque

        deque还有push_front(将元素插入到前面)和pop_front(删除最前面的元素)操作,复杂度是O(1)

4. list容器

        双向链表

        它的底层实现不是数组,所以不支持随机存取

        在任何位置插入删除都是常数时间,不支持随机存取

        除了具有所有顺序容器都具有的成员函数以外(差不多vector有的它都有),还支持8个成员函数:

                push_front:在前面插入

                pop_front:删除前面的元素

                sort:排序(list不支持STL的算法sort)(毕竟这是list,而不是数组之类,STL库的sort算法只支持可以随机访问的迭代器)

                remove:删除和指定值相等的所有元素

                unique:删除所有和前一个元素相同的元素(要做到元素不重复,则unique之前还需要sort)

                merge:合并两个链表,并清空被合并的那个

                reverse:颠倒链表

                splice:在指定位置前面插入另一链表中的一个或多个元素,并在另一链表中删除被插入的元素

        样例:

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

class A
{
private:
    int n;
public:
    A(int n_) { n = n_;}
    friend bool operator<( const A & a1, const A & a2);
    friend bool operator==( const A & a1, const A & a2);
    friend ostream & operator<<( ostream & o, const A & a);
};
bool operator<(const A & a1, const A & a2)
{
    return a1.n < a2.n;
}
bool operator==(const A & a1, const A & a2)
{
    return a1.n == a2.n;
}
ostream & operator<<( ostream & o, const A & a)
{
    o << a.n;
    return o;
}
template<class T>
void PrintList(const list<T> & lst)
{//不推荐的写法,还是用两个迭代器作为参数会更好
    typename list<T>::const_iterator i;
    i = lst.begin();
    for ( i = lst.begin(); i != lst.end(); i++)
    {
        cout<< *i << ",";
    }
    //typename可以用来说明list<T>::const_iterator是个类型
    //在vs中不写也可以
}



int main(int argc, char const *argv[])
{
    list<A> lst1,lst2;
    lst1.push_back(1);
    lst1.push_back(2);
    lst1.push_back(3);
    lst1.push_back(4);
    lst1.push_back(2);

    lst2.push_back(10);
    lst2.push_front(20);
    lst2.push_back(30);
    lst2.push_back(30);
    lst2.push_back(30);
    lst2.push_front(40);
    lst2.push_back(40);

    cout<<"1)";
    PrintList(lst1);
    cout<<endl;//输出:1)1,2,3,4,2,
    cout<<"2)";
    PrintList(lst2);
    cout<<endl;//输出:2)40,20,10,30,30,30,40,

    lst2.sort();
    cout<<"3)";
    PrintList(lst2);
    cout<<endl;//输出:3)10,20,30,30,30,40,40,

    lst2.pop_front();
    cout<<"4)";
    PrintList(lst2);
    cout<<endl;//输出:4)20,30,30,30,40,40,

    lst1.remove(2);//删除所有和A(2)相等的元素
    cout<<"5)";
    PrintList(lst1);
    cout<<endl;//输出:5)1,3,4,

    lst2.unique();//删除所有和前一个元素相等的元素
    cout<<"6)";
    PrintList(lst2);
    cout<<endl;//输出:6)20,30,40,

    lst1.merge(lst2);//合并lst2到lst1并清空lst2
    cout<<"7)";
    PrintList(lst1);
    cout<<endl;//输出:7)1,3,4,20,30,40,

    cout<<"8)";
    PrintList(lst2);
    cout<<endl;//输出:8)

    lst1.reverse();
    cout<<"9)";
    PrintList(lst1);
    cout<<endl;//输出:9)40,30,20,4,3,1,

    lst2.push_back(100);
    lst2.push_back(200);
    lst2.push_back(300);
    lst2.push_back(400);
    list<A>::iterator p1,p2,p3;
    p1 = find(lst1.begin(),lst1.end(),3);
    p2 = find(lst2.begin(),lst2.end(),200);
    p3 = find(lst2.begin(),lst2.end(),400);
    lst1.splice(p1,lst2,p2,p3);
    //将[p2,p3)插入p1之前,并从lst2中删除[p2,p3)

    cout<<"10)";
    PrintList(lst1);
    cout<<endl;//输出:10)40,30,20,4,200,300,3,1,
    cout<<"11)";
    PrintList(lst2);
    cout<<endl;//输出:11)100,400,

    return 0;
}

        这个样例基本把list的主要用法都包含进去了。

后记:

        这些东东基本上都是那种你知道了一个,其他的就都能推导出来的那种知识,如果不想死记硬背的话,其实用好IDE自带的功能,记好基本的用法就能自由使用了。放假了,不能摸鱼,要认真学习,为将来做好准备(生怕被淘汰的我)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值