关于容器我们知道的在STL中有关联容器和顺序容器,那么所谓的关联容器是什么?所谓的顺序容器又是什么呢?在STL中的哪些属于关联容器,哪些属于顺序容器呢?下面来做一个简单的介绍:关联容器中的元素是按照关键字来保存和访问的,C++中的关联容器重要就是map和set。而顺序容器是按照元素在容器中的位置来进行保存和访问的,在C++中的顺序容器是Vector、List、Deque。今天我就关联容器来给大家做一个简单的介绍。
一、set(集合)
set是一种key结构,set是能够存储同一数据类型的数据结构,经过存入set的数据会自动的进行排序,set的底层是用红黑树来进行实现的。
1、插入:insert()
1)pair
在迭代器中插入一个数据,如果这个数据不存在就直接插入,其返回值为插入后元素的迭代器和true。如果这个元素已经存在,那么返回当前元素以及false.
在这里补充一下pair,pair是一种模板模型,每个pair可以存储两个值,这俩个值得类型是任意类型。定义在#include
template struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& x, const T2& y) : first(x), second(y) {}
template
pair (const pair &p) : first(p.first), second(p.second) { }
}
pair我们可以看到pair有两个成员分别是first和second,set是一个模板,first是一个指向要插入位置的迭代器,如果second是false则first就是已经存在的元素的这个位置的迭代器,如果second为true,first就是要插入位置的迭代器。
2)iterator insert ( iterator position, const value_type& x )
在指定的位置插入指定的数据,position是一个迭代器的位置,x表示的是要插入的数。如果插入成功的话,会返回一个插入新位置的迭代器。
2)template
插入一段迭代器区间
2、删除(erase)
1)void erase(iterator position)
删除一个迭代器位置
2)size_type erase(sonst key_type& x)
删除成功的话就返回1
3)void erase(iterator first, iterator last)
删除一段迭代器区间
3、查找:find()
iterator find(const key_type& x) const;
若找到返回该迭代器的位置,否则就返回的是最后一个元素后面的位置
4、数量:count()
size_type count(const key_type& x)const
count是为了统计某个数值出现的次数,在set里面不能重复出现相同的数值,count的返回值只有0和1两个值,0表示的是不存在,1表示存在。
关于set的用法我将通过下面的代码展示来给大家做一个进一步的说明
#include
using namespace std;
#include
void fun(set myset)
{
set::iterator it;
for (it=myset.begin(); it!=myset.end(); it++)
{
cout <<*it<<" ";
}
cout << endl;
}
void TestSet()
{
set t;
set::iterator it;
pair::iterator,bool> ret;
t.insert(1);
t.insert(2);
t.insert(3);
t.insert(4);
t.insert(5);
fun(t);
cout<
程序的输出结果是:
有别于set的是,map是一种key(键),value(值)的形式,用来保存键和值组成的集合,键必须是唯一的,但值可以不唯一。里面的元素可以根据键进行自动排序,由于map是key_value的形式,所以map里的所有元素都是pair类型。pair里面的first被称为key(键),second被称为value(值)。map的底层是用红黑树来实现的,关于创建pair类型有下面几种方法:
pair("苹果",5);
make_pair("西瓜",1);
pair p = {"菠萝",3};
make_pair :
template 下面来简单看一下make_pair的用法:
template
pair make_pair (T1 x, T2 y)
{
return ( pair(x,y) );
}
在刚开始介绍set的时候,简单介绍了一下pair。那么现在便将pair和make_pair再做一个详细的补充吧
1、pair:
pair是将两个数据合成一个数据,当有这样的需求时就要用到pair,就是map。还有一个运用就是函数要返回连个数据的时候要用到pair,pair是一个结构体,因为两个成员变量用的是struct而不是class。
2、make_pair:
我们可以使用pair的构造函数,也可以使用make_pair来生成我们需要的pair。一般来说,在需要pair的时候我们用ake_pair来生成pair的对象很方便,但由于pair可以进行隐示的类型转换局带来一些问题,如下:
std::pair(1, 1.1);
std::make_pair(1, 1.1);
好了,介绍到这里就要言归正传回来说map
1、插入:insert()
1)pair
插入一个value_type类型,返回的则是一个pair类型。pair
2)iterator insert ( iterator position, const value_type& x );
在一个迭代器的位置插入一个value_type类型,插入成功的话就返回新插入位置的迭代器,否则就返回传入的迭代器。
3)template
void insert ( InputIterator first, InputIterator last );
插入的是一段迭代器区间
2、删除:erase()
1)void erase ( iterator position );
删除的是position位置的元素
2)size_type erase ( const key_type& x );
删除的是键值所在的位置,成功为1,否则为0
3)void erase ( iterator first, iterator last );
删除一段迭代器区间
3、查找:find()
iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;
查找成功的话会返回这个元素的迭代器,否则返回的是end
4、count:
size_type count ( const key_type& x ) const;
和set中的count使用功能相同
5、operator[]:
T& operator[] ( const key_type& x );
operator[]是很常用的,如果map中有这个x,则它就把这个x所对应的value的引用返回。如果map中没有这个x的话,则它会调用insert(pair
下面是一个通过map统计水果出现次数的问题:
第一种:
void CountFruit(vector t)
{
map countMap;
for(size_t i = 0; i < t.size(); ++i)
{
map::iterator ret = countMap.find(t[i]);
if(ret != countMap.end())
{
ret->second++;
//(*ret).second++;
}
else
{
countMap.insert(pair(t[i],1));
}
}
}
这种方法会遍历两次,find遍历一次,insert也要遍历一次。而且必须先进行查找,如果已存在second++,不存在直接插入就好
第二种:
void CountFruit(vector t)
{
map countMap;
for(size_t i = 0; i< t.size(); ++i)
{
pair
第三种:
void CountFruit(vector t)
{
map countMap;
for(size_t i = 0; i < t.size(); ++i)
{
countMap[t[i]]++;
}
}
这种用的是operator[]没有的话就插入,有就返回value的引用。
operator[]实现的是:1、读取key的值,2、修改second的值。给定关键字key返回key对应pair的second的引用