cpp containers

容器(containers)

容器用来管理某类对象。为了应付程序中的不同需求,STL 准备了两类共七种基本容器类型:

序列式容器(Sequence
containers),此为可序群集,其中每个元素均有固定位置—取决于插入时机和地点,和元素值无关。如果你以追加方式对一个群集插入六个元素,它们的排列次序将和插入次序一致。STL提供了三个序列式容器:向量(vector)、双端队列(deque)、列表(list),此外你也可以把
string 和 array 当做一种序列式容器。 关联式容器(Associative
containers),此为已序群集,元素位置取决于特定的排序准则以及元素值,和插入次序无关。如果你将六个元素置入这样的群集中,它们的位置取决于元素值,和插入次序无关。STL提供了四个关联式容器:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。

  1. vector:

优点:支持随机访问,即 [] 操作和 .at(),所以查询效率高。

缺点:当向其头部或中部插入或删除元素时,为了保持原本的相对次序,插入或删除点之后的所有元素都必须移动,所以插入的效率比较低。

适用场景:适用于对象简单,变化较小,并且频繁随机访问的场景。

//定义一个vector 插入6个元素,然后打印所有元素
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    vector<int> vecTemp;

    for (int i = 0; i<6; i++)
        vecTemp.push_back(i);

    for (int i = 0; i<vecTemp.size(); i++)
        cout << vecTemp[i] <<" "; // 输出:0 1 2 3 4 5

    return 0;
}

2.deque:

优点:支持随机访问,即 [] 操作和 .at(),所以查询效率高;可在双端进行 pop,push。

缺点:不适合中间插入删除操作;占用内存多。

适用场景:适用于既要频繁随机存取,又要关心两端数据的插入与删除的场景。

//声明一个浮点类型的deque,并在容器尾部插入6个元素,最后打印所有元素。
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    deque<float> dequeTemp;

    for (int i = 0; i<6; i++)
        dequeTemp.push_back(i);

    for (int i = 0; i<dequeTemp.size(); i++)
        cout << dequeTemp[i] << " "; // 输出:0 1 2 3 4 5

    return 0;
}

3.list

优点:内存不连续,动态操作,可在任意位置插入或删除且效率高。

缺点:不支持随机访问。

适用场景:适用于经常进行插入和删除操作并且不经常随机访问的场景。

//产生一个空list,将a至z的所有字符插入其中,循环每次打印移除集合的第一个元素,从而打印出所有元素
#include <iostream>
#include <list>

using namespace std;

int main(int argc, char* argv[])
{
    list<char> listTemp;

    for (char c = 'a'; c <= 'z'; ++c)
        listTemp.push_back(c);

    while (!listTemp.empty())
    {
        cout <<listTemp.front() << " ";
        listTemp.pop_front();
    }

    return 0;
}

成员函数empty()的返回值告诉我们容器中是否还有元素,只要这个函数返回
false,循环就继续进行。循环之内,成员函数front()会返回第一个元素,pop_front()函数会删除第一个元素。

4.set

优点:使用平衡二叉树实现,便于元素查找,且保持了元素的唯一性,以及能自动排序。

缺点:每次插入值的时候,都需要调整红黑树,效率有一定影响。

适用场景:适用于经常查找一个元素是否在某群集中且需要排序的场景。

#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> setTemp;

    setTemp.insert(3);
    setTemp.insert(1);
    setTemp.insert(2);
    setTemp.insert(1);

    set<int>::iterator it;
    for (it = setTemp.begin(); it != setTemp.end(); it++)
    {
        cout << *it << " ";
    }

    return 0;
}
//输出结果:1 2 3。一共插入了 4 个数,但是集合中只有 3 个数并且是有序的,可见之前说过的 set 集合的两个特点,有序和不重复。
//当 set 集合中的元素为结构体时,该结构体必须实现运算符 ‘<’ 的重载:
#include <iostream>
#include <set>
#include <string>

using namespace std;

struct People
{
    string name;
    int age;

    bool operator <(const People p) const
    {
        return age < p.age;
    }
};

int main(int argc, char* argv[])
{
    set<People> setTemp;

    setTemp.insert({"张三",14});
    setTemp.insert({ "李四", 16 });
    setTemp.insert({ "隔壁老王", 10 });

    set<People>::iterator it;
    for (it = setTemp.begin(); it != setTemp.end(); it++)
    {
        printf("姓名:%s 年龄:%d\n", (*it).name.c_str(), (*it).age);
    }

    return 0;
}

/*
输出结果
姓名:王二麻子 年龄:10
姓名:张三 年龄:14
姓名:李四 年龄:16 
*/ 

5.map

优点:使用平衡二叉树实现,便于元素查找,且能把一个值映射成另一个值,可以创建字典。

缺点:每次插入值的时候,都需要调整红黑树,效率有一定影响。

适用场景:适用于需要存储一个数据字典,并要求方便地根据key找value的场景。

#include "stdafx.h"
#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<int, string> mapTemp;

    mapTemp.insert({ 5,"张三" });
    mapTemp.insert({ 3, "李四"});
    mapTemp.insert({ 4, "隔壁老王" });

    map<int, string>::iterator it;
    for (it = mapTemp.begin(); it != mapTemp.end(); it++)
    {
        printf("学号:%d 姓名:%s\n", (*it).first, (*it).second.c_str());
    }

    return 0;
}

/*
输出结果:
学号:3 姓名:李四
学号:4 姓名:隔壁老王
学号:5 姓名:张三
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值