这里来介绍两个关联式的容器 map 和 set 学习并且使用
一 set
set的特性是,所有的元素都会根据元素的键值自动被排序,且set只有键值,(可以看他的模板类)
set的底层是用红黑树写的,set的接口只要传递调用即可
不可以通过set的迭代器来改变set的元素值,因为set的元素值就是其键值,关系到set的排序规则。set<T>::iterator被定义为底层RB-tree的const_iterator,杜绝写入操作。
set 里面的数据输出是有序的,走的是红黑树的中序遍历
插入重复值,set会放沉余,起到了过滤的作用
先从库里面查set 。
其模板类为
template < class Key, class Compare = less<Key>,
class Allocator = allocator<Key> >
class set;
其接口如下图
我们首先先看一下 insert的使用
pair<iterator,bool> insert ( const value_type& x );
iterator insert ( iterator position, const value_type& x );
template <class InputIterator>
iterator insert ( iterator position, const value_type& x );
template <class InputIterator>
void insert ( InputIterator first, InputIterator last );
在这里还是先介绍一下pair
其模拟实现如下
template
<
class
T,
class
V>
struct
pair
{
T first;
V second;
pair(
const
K& key,
const
V& value)
:first(key)
,second(value)
{}
};
pair<K, V> make_pair(
const
K& key,
const
V& value)
{
return
pair<K, V>(key, value);
}
具体set的代码如下:
set<int,greater<int>> s1;
s1.insert(5);
s1.insert(3);
s1.insert(4);
s1.insert(3);
set<int,greater<int>>::const_iterator s_it = s1.begin();
while (s_it != s1.end())
{
cout<<*s_it<<" ";
++s_it;
}
cout<<endl;
s_it = s1.begin();
pair<set<int, greater<int>>::const_iterator, bool> ret;
ret = s1.insert(10);
s1.erase(3);
s_it = s1.begin();
while (s_it != s1.end())
{
cout<<*s_it<<" ";
++s_it;
}
cout<<endl;
s_it = s1.begin();
s1.insert (s_it,11);
s_it = s1.begin();
while (s_it != s1.end())
{
cout<<*s_it<<" ";
++s_it;
}
cout<<endl;
int arr[]= {7,8,9};
s1.insert(arr,arr+3);
s_it = s1.begin();
while (s_it != s1.end())
{
cout<<*s_it<<" ";
++s_it;
}
cout<<endl;
二,map
map的特性是,所有元素都会根据元素的键值自动被排序,map的所有元素都是pair(可以理解为k,v);
同样底层是红黑树,不可以通过迭代器来修改元素的内容。
map的模板类如下
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
map的接口如下图
map 的insert 同 set一样
pair<iterator,bool> insert ( const value_type& x );
iterator insert ( iterator position, const value_type& x );
template <class InputIterator>
iterator insert ( iterator position, const value_type& x );
template <class InputIterator>
void insert ( InputIterator first, InputIterator last );
用法和规则相差无几。
这里我们来写一个简单的程序来熟悉使用map
question:统计大家最喜欢吃的几种水果。
//解法一
string strs[] = {"橘子","苹果","香蕉","梨","西瓜","枣","弥胡桃","菠萝","橘子","杏"};
map<string, int> countmap;
for (size_t i = 0; i < sizeof(strs)/sizeof(strs); ++i)
{
map(string, int)::iterator it = countmap.find(strs[i]);
if(it != countmap.end())
{
it->second++;
}
else
{
countmap.insert(pair<string, int>(strs[i], 1));
}
}
//解法二
string strs[] = {"橘子","苹果","香蕉","梨","西瓜","枣","弥胡桃","菠萝","橘子","杏"};
map<string, int> countmap;
pair<map<string, int>::iterator, bool> ret;
for (size_t i = 0; i < sizeof(strs)/sizeof(strs); ++i)
{
ret = countmap.insert(pair<string, int>(strs[i],1));
if (ret.second == false)
{
ret.first->second++;
}
}
//解法三
string strs[10] = {"橘子","苹果","香蕉","梨","西瓜","枣","弥胡桃","菠萝","橘子","杏"};
map<string, int> countmap;
for (size_t i = 0; i < sizeof(strs)/sizeof(strs[0]); ++i)
{
countmap[strs[i]]++;
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = insert(make_pair(key, value));//这里不是map的insert
return ret.first->second;
}