map和multimap是两种关联容器,他们的元素是一些关键字——值(key-value)对:关键字起索引作用,值则表示与索引相关联的数据。它们的元素都是以键为标准进行的strict weak ordering(严格弱序化)的排序。
首先先介绍一下map的元素类型:
map::key_type
这个是map的关键字的类型。map::mapped_type
这个是与关键字相关的值的类型。value_type
这个类型是map中整个键值对的类型,其实它是下面的定义typedef pair
。
既然前面说了,map是以键的严格弱序化进行排序的,那么有必要对严格弱序化进行说明,按照维基所说:
严格弱序化具有下面的特性,假设x和y是属于S的元素
1. For all x, it is not the case that x < x (irreflexivity).(即在stl的算法函数中若两个相同的容器对象做比较,返回false)
2. For all x ≠ y, if x < y then it is not the case that y < x (asymmetric).
3. For all x, y, and z, if x < y and y < z then x < z (transitivity).
4. For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of equivalence).
构造函数有很多类型,可以构造一个空map,也可以用一个迭代器范围构造,还可以使用初始化列表进行构造。并且在构造函数中我们还可以利用函数指针或者函数对象作为参数来制定键的排列顺序。
// 构造空map
explicit map (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
explicit map (const allocator_type& alloc);
// 利用迭代器范围构造
template <class InputIterator>
map (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& = allocator_type());
// 拷贝构造函数
map (const map& x);
map (const map& x, const allocator_type& alloc);
// 列表构造
map (initializer_list il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
参数说明:
less
.构造函数的使用例子:
#include
#include
bool fncomp (char lhs, char rhs) {
return lhsstruct classcomp {
bool operator() (const char& lhs, const char& rhs) const
{
return lhsint main ()
{
std::map<char,int> first;
first['a']=10;
first['b']=30;
first['c']=50;
first['d']=70;
std::map<char,int> second (first.begin(),first.end());
std::map<char,int> third (second);
std::map<char,int,classcomp> fourth; // class as Compare
bool(*fn_pt)(char,char) = fncomp;
std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare
return 0;
}
// 列表构造
map<string, string> authors = {
{
"Joyce", "James"},
{
"Austen", "Jane"},
{
"Dickens", "Charles"}
}
特别注意,当使用函数对象的时候,只需要在模板类型中指明函数对象类型就行,但是使用函数指针的时候,除了在模板类型中指明,还要在构造函数中使用。
map可以通过迭代器进行遍历,而且它的迭代器是双向迭代器,可以前后移动。
可以通过begin()
和end()
获得开始迭代器和尾后迭代器。
可以通过cbegin()
和cend()
获得const_iterator
,即通过迭代器不能修改元素的值。
map<int, int> mm(first, last);
map<int, int>::iterator it = mm.begin();
for(; it != mm.end(); it++)
cout << it->first << " " << it->second << endl;
上面first表示key,second表示value。
添加元素可以分为添加单个元素或者范围添加
map<string, int> words;
// 方式1
words.insert(pair<string, int>("apple", 3));
// 方式2
words.insert(map<string, int>::value_type("apple", 3));
// 方式3
words["apple"] = 3;
// 方式4
words.at("apple") = 3;
//范围添加
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
void insert (initializer_list il);
需要解释一下[]和at()
添加元素的方式,当键在map中不存在的时候,这两条语句相当于添加元素。但是当map中存在所指键的时候,只是将键的对应的value进行改变。
at()
比起[]的优点在于当传进的参数和键的类型不同的时候,at()
会抛出异常。
iterator erase (const_iterator position);
size_type erase (const key_type& k);
iterator erase (const_iterator first, const_iterator last);
void clear();
第一个函数利用迭代器指向删除的元素。
其中第二个函数返回删除元素的个数,若键k在map中存在,则返回1,否则返回0(map中相同键只有一个)。
第三个函数删除范围[first, last)中的元素。
第四个表示清空map。
iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
查找元素利用键k去查找,找到的话返回指向该元素的迭代器,没有找到的话就返回map::end
。
size_type count (const key_type& k) const;
这个函数返回键k在map中出现的次数,由于map中相同键只能出现一次,因此返回值最大为1。
#include
#include
int main ()
{
std::map<char,int> mymap;
std::map<char,int>::iterator it;
mymap['a']=50;
mymap['b']=100;
mymap['c']=150;
mymap['d']=200;
it = mymap.find('b');
if (it != mymap.end())
mymap.erase (it);
// print content:
std::cout << "elements in mymap:" << '\n';
std::cout << "a => " << mymap.find('a')->second << '\n';
std::cout << "c => " << mymap.find('c')->second << '\n';
std::cout << "d => " << mymap.find('d')->second << '\n';
return 0;
}
运行结果:
elements in mymap:
a => 50
c => 150
d => 200
map中的swap是两个容器的交换。
#include
#include
using namespace std;
int main( )
{
map <int, int> m1, m2, m3;
map <int, int>::iterator m1_Iter;
m1.insert ( pair <int, int> ( 1, 10 ) );
m1.insert ( pair <int, int> ( 2, 20 ) );
m1.insert ( pair <int, int> ( 3, 30 ) );
m2.insert ( pair <int, int> ( 10, 100 ) );
m2.insert ( pair <int, int> ( 20, 200 ) );
m3.insert ( pair <int, int> ( 30, 300 ) );
cout << "The original map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter->second;
cout << "." << endl;
// This is the member function version of swap
//m2 is said to be the argument map; m1 the target map
m1.swap( m2 );
cout << "After swapping with m2, map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
cout << "After swapping with m2, map m2 is:";
for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
// This is the specialized template version of swap
swap( m1, m3 );
cout << "After swapping with m3, map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
system("pause");
}
empty() 如果map为空则返回true
get_allocator() 返回map的配置器
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
upper_bound() 返回键值>给定元素的第一个位置
size() 返回map中元素的个数
multimap中的键也是按照构造函数中所指定的二元谓词进行排序的。
multimap的元素类型和map是一致的,这里就不在赘述。
这里就简要概述一下multimap和map不同的地方:multimap中相同的键可以多次出现,而不像map只能出现一次。
在multimap中没有定义[]运算符,当然也没有定义at()成员函数,因此,multimap进行插入的时候,只能利用insert()函数进行插入。