STL组件之——容器

        ①容器containers,用来管理某类对象的集合,为了应对不同的需求,STL 准备了不同的容器类型。

        ② 迭代器Iterators,用来在一个对象群集的元素上进行遍历动作。迭代器的主要好处是为所有容器提供了一组很小的公共接口,利用这个接口,某项操作就可以进行至群集内的下一个元素。

        ③算法Algorithm,用来处理集群内的元素,可以出于不同的目的使用那些元素。通过迭代器的帮助,只需要撰写一次算法,就可以将它应用在任意容器上。

STL的基本观念就是将数据和操作分离,数据由容器类别加以管理,操作则由可定制的算法定义。迭代器在两者之间充当粘合剂,使任何算法都可以和任何容器交互运作。

        容器用来管理一组元素,为了适应不同需要,STL提供了不同类型的容器,总体上可以分为两类:

        ①序列式容器。是可序群集,其中每个元素均有固定位置——取决于插入时机和地点,与元素值无关。如果以追加方式对一个群集置入元素,它们的排列顺序将和置入次序一致。STL提供了三个此类容器:vector、deque、list

        ②关联式容器。是已序群集,元素位置取决于特定的排序准则,如果以追加方式对一个群集置入元素,它们的排列顺序取决于元素值,和插入次序无关。STL提供了四个此类容器:set、multiset、map、multimap

序列式容器:

  • vector

        vector将其元素置于一个动态数组中加以管理。允许随机存取,即就是可以利用索引直接存取任何一个元素,在尾部添加元素或删除元素非常快速,但是在头部或中部安插元素比较费劲,为了保持原本的相对次序,安插点之后的所有元素都必须移动。

下面的例子针对整数类型定义了一个vector,并填充6个元素

#include<iostream>
#include<vector>
using namespace std;
int main()
{
        vector<int> col;
        for(int i=1;i<=6;++i)
        {
                col.push_back(i);
        }
        for(int i=0;i<col.size();++i)
        {
                cout<<col[i]<<" ";
        }
        cout<<endl;
}

输出结果如下                

  •  Deque

        deque,就是“double-ended queue"的缩写。它是一个动态数组,可以在两端对其进行操作,因此不论在尾部还是头部安插删除元素都非常迅速,而在中间部分对元素进行操作时必须移动其他元素,所以比较费时。

声明一个浮点数类型的deque,并在头部安插1.1到6.6共6个元素。

#include<iostream>
#include<deque>
using namespace std;
int main()
{
        deque<float> col;
        for(int i=1;i<=6;++i)
        {
                col.push_front(i*1.1);
        }
        for(int i=0;i<col.size();++i)
        {
        cout<<col[i]<<" ";
        }
        cout<<endl;
}
~    

输出结果为

 我们可以观察到最终元素结果与安插次序恰好相反,因为每个元素都安插在上一个元素的前面。当然也可以使用push_back()在尾部添加元素,此时元素的顺序又会发生变化

  •  List

        List由双向链表组成,这意味着list内的每个元素都有部分内存用来指示其前趋元素和后继元素。List不提供随机存取,因此如果要对某一元素进行操作,则必须按链表顺序依次走过前面的元素。List的优势是在任何位置安插或删除元素都非常快,因为只需改变链接就行。

        下面例子产生一个空list,将‘a'至'z’的所有字符插入其中,利用循环每次打印并移除集群的首元素,从而打印出所有元素

#include<iostream>
#include<list>
using namespace std;
int main()
{
        list<char> col;
        for(char c='a';c<='z';++c)
        {
                col.push_back(c);
        }
        while(!col.empty())
        {
                cout<<col.front()<<" ";
                col.pop_front();
        }
        cout<<endl;
}

运行结果如下

 其成员函数empty()的返回值告诉我们容器中是否还有元素,而成员函数front()会返回第一个元素,成员函数pop_front()函数会删除第一个元素。

        也可以将string当作STL容器来使用,它和vectors很相似,只不过其元素为字符。

        另一种容器不是类别(class),而是C++语言核心所支持的一个型别:具有静态大小或动态大小的array,但array并非STL容器,它们并没有类似size(),empty()等成员函数,尽管如此,STL的设计允许针对array调用STL算法。

关联式容器

上面列举的几种STL容器都是序列式容器,接下来将介绍关联式容器,其依据特定的排序准则,自动为其元素排序,排序准则以函数形式呈现,用来比较元素值或元素键。缺省情况下默认以operator<进行比较。

关联式容器的差别主要在于元素的类型以及处理重复元素时的方法。

  • set。其内部元素依据其值自动排序,每个元素值只能出现一次,不允许重复;
  • Multiset。它和set相同,只不过它允许重复元素,也就是说multiset可包括多个数值相同的元素;

下面展示如何在set中安插元素,并使用迭代器打印他们

#include<iostream>
#include<set>
using namespace std;
int main()
{
        set<int> col;
        col.insert(3);
        col.insert(1);
        col.insert(5);
        col.insert(4);
        col.insert(1);
        col.insert(6);
        col.insert(2);

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

 

 在这里我们利用成员函数insert()插入元素,会发现元素不仅自动排列好了顺序,而且我们插入的重复元素并不会重复出现。

如果想使用multiset而不是set,只需要改变容器类型即可,(set和multiset在同一个头文件里)。运行结果如下

  • map。 它的元素都是”实值/键值“所形成的一个对组((pair),还记得我之前的文章里提到的pair吗?就是它。)每个元素有一个键,是排序准则的基础,每个键只能出现一次,不允许重复
  • Multimap。 它和map相同,但允许重复元素,它可以包含多个键值相同的元素。

下面是一个multimap的例子

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
        multimap<int,string> col;
        col.insert(make_pair(5,"tagged"));
        col.insert(make_pair(2,"a"));
        col.insert(make_pair(1,"this"));
        col.insert(make_pair(4,"of"));
        col.insert(make_pair(6,"strings"));
        col.insert(make_pair(1,"is"));
        col.insert(make_pair(3,"multimap"));

        multimap<int,string>::iterator it;
        for(it=col.begin();it!=col.end();++it);
        {
                cout<<it->second<<" ";
        }
        cout<<endl;
}

所有关联式容器都有一个可供选择的template参数,指明排序准则。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值