std::map 简介及其使用

注:std::map C++11标准

 

map概述

template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

  Map是一种关联容器,它按照特定顺序存储由键值Key和映射值Value组合而成的元素

  在map键值Key通常用于排序和唯一标识元素,而映射值Value存储与此键值Key相关联的内容。键Key和映射值Value的类型可能不同,并在成员类型value_type中组合在一起,value_type是一个组合了这两种类型的pair类型:typedef pair<const Key, T> value_type。

  在map内部,元素总是按照其键Key进行排序的,排序时使用其内部比较对象(Compare)并遵循指定的严格弱序准则。

  Map容器通常比unordered_map容器在按键Key访问元素的速度上要,但它们允许根据子集的顺序直接迭代子集

  Map中的映射值可以通过对应的键Key使用括号操作符(operator[])直接访问。

  Map通常是基于二叉搜索树实现的。

 

容器属性

  • 关联

  关联容器中的元素由其引用,而不是由它们在容器中的绝对位置引用。

  • 有序

  容器中的元素始终遵循严格的顺序。所有插入的元素都按这个顺序给定一个位置。

  • 映射

  每个元素都将一个键关联到一个映射值:键用于标识其内容为映射值的元素。

  • 键值唯一

  容器中没有两个元素可以具有等效

  • 分配器

  容器使用allocator对象来动态处理其存储需求。

 

模板参数

  • Key

  键的类型。Map中的每个元素都由其键值唯一标识。别名为成员类型map::key_type。

  • T

  映射值的类型。Map中的每个元素都将一些数据存储为其映射值。别名为成员类型map::mapped_type

  • Compare

  一个二进制谓词,它接受两个键值作为参数并返回一个bool值。表达式 comp(a, b) 中,comp是Compare类型的对象,a和b是键值,如果在函数定义的严格弱序中,a被认为在b之前,则表达式comp(a, b)应该返回true。Map对象使用这个表达式来确定容器中元素的顺序以及两个元素的键是否相等。Map容器中的任何两个元素都不能具有相同的键。Compare可以是函数指针或函数对象,默认为 less<T>,其返回与使用小于操作符(a<b)相同的结果。别名为成员类型map::key_compare。

  • Alloc

  分配器对象的类型,用于定义存储分配模型。默认情况下,使用allocator类模板,该模板定义最简单的内存分配模型,并且与值无关。别名为成员类型map::allocator_type。

 

成员类型 

member typedefinitionnotes
key_type The first template parameter (Key)  
mapped_type The second template parameter (T)  
value_type pair<const key_type,mapped_type>  
key_compare The third template parameter (Compare) defaults to: less<key_type>
value_compare Nested function class to compare elements see value_comp
allocator_type The fourth template parameter (Alloc) defaults to: allocator<value_type>
reference value_type&  
const_reference const value_type&  
pointer allocator_traits<allocator_type>::pointer for the default allocator: value_type*
const_pointer allocator_traits<allocator_type>::const_pointer for the default allocator: const value_type*
iterator a bidirectional iterator to value_type convertible to const_iterator
const_iterator a bidirectional iterator to const value_type  
reverse_iterator reverse_iterator<iterator>  
const_reverse_iterator reverse_iterator<const_iterator>  
difference_type a signed integral type, identical to:
iterator_traits<iterator>::difference_type
usually the same as ptrdiff_t
size_type an unsigned integral type that can represent any non-negative value of difference_type usually the same as size_t

 

成员函数

  • 构造函数(constructor)
empty (1)
explicit map (const key_compare& comp = key_compare(),
              const allocator_type& alloc = allocator_type());
explicit map (const allocator_type& alloc);
range (2)
template <class InputIterator>
map (InputIterator first, InputIterator last,
     const key_compare& comp = key_compare(),
     const allocator_type& = allocator_type());
copy (3)
map (const map& x);
map (const map& x, const allocator_type& alloc);
move (4)
map (map&& x);
map (map&& x, const allocator_type& alloc);
initializer list (5)
map (initializer_list<value_type> il,
     const key_compare& comp = key_compare(),
     const allocator_type& alloc = allocator_type());

  构造函数示例:

// constructing maps
#include <iostream>
#include <map>

bool fncomp (char lhs, char rhs) {return lhs<rhs;}

struct classcomp {
  bool operator() (const char& lhs, const char& rhs) const
  {return lhs<rhs;}
};

int 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;
}
构造函数示例
  • 析构函数(destructor)
~map();
  • 赋值(operator=)
copy (1)
map& operator= (const map& x);
move (2)
map& operator= (map&& x);
initializer list (3)
map& operator= (initializer_list<value_type> il);

  赋值示例:

// assignment operator with maps
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> first;
  std::map<char,int> second;

  first['x']=8;
  first['y']=16;
  first['z']=32;

  second=first;                // second now contains 3 ints
  first=std::map<char,int>();  // and first is now empty

  std::cout << "Size of first: " << first.size() << '\n';
  std::cout << "Size of second: " << second.size() << '\n';
  return 0;
}

Output:
Size of first: 0
Size of second: 3
赋值示例
  • 迭代器(Iterators

 

  迭代器示例:

// map::begin/end
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap['b'] = 100;
  mymap['a'] = 200;
  mymap['c'] = 300;

  // show content:
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
a => 200
b => 100
c => 300
迭代器示例
  • 容器大小或容量相关(Capacity
函数 函数原型 功能描述
empty bool empty() const noexcept; Test whether container  is empty 
size size_type size() const noexcept; Return container size 
max_size size_type max_size() const   noexcept; Return maximum size 
  • 成员访问(Element access
函数 函数原型 功能描述
operator[] mapped_type& operator[]   (const key_type& k); Access element 
mapped_type&   operator[] (key_type&& k);
at mapped_type& at (const   key_type& k); Access element 
const   mapped_type& at (const key_type& k) const;

  成员访问示例:

// accessing mapped values
#include <iostream>
#include <map>
#include <string>

int main ()
{
  std::map<char,std::string> mymap;

  mymap['a']="an element";
  mymap['b']="another element";
  mymap['c']=mymap['b'];

  std::cout << "mymap['a'] is " << mymap['a'] << '\n';
  std::cout << "mymap['b'] is " << mymap['b'] << '\n';
  std::cout << "mymap['c'] is " << mymap['c'] << '\n';
  std::cout << "mymap['d'] is " << mymap['d'] << '\n';

  std::cout << "mymap now contains " << mymap.size() << " elements.\n";

  return 0;
}

Notice how the last access (to element 'd') inserts a new element in the map with that key and
initialized to its default value (an empty string) even though it is accessed only to retrieve
its value. Member function map::find does not produce this effect.
Output:
mymap['a'] is an element
mymap['b'] is another element
mymap['c'] is another element
mymap['d'] is
mymap now contains 4 elements.
----------------------------------------------------------------------------------------
// map::at
#include <iostream>
#include <string>
#include <map>

int main ()
{
  std::map<std::string,int> mymap = {
                { "alpha", 0 },
                { "beta", 0 },
                { "gamma", 0 } };

  mymap.at("alpha") = 10;
  mymap.at("beta") = 20;
  mymap.at("gamma") = 30;

  for (auto& x: mymap) {
    std::cout << x.first << ": " << x.second << '\n';
  }

  return 0;
}

Possible output:
alpha: 10
beta: 20
gamma: 30

成员访问示例
成员访问示例
  • 添加、删除等修改相关操作(Modifiers
函数 函数原型 功能描述
insert pair<iterator,bool> insert   (const value_type& val);
    template <class P> pair<iterator,bool> insert (P&&   val);
Insert elements
iterator   insert (const_iterator position, const value_type& val);
    template <class P> iterator insert (const_iterator position,   P&& val);
template   <class InputIterator>
    void insert (InputIterator first, InputIterator last);
void   insert (initializer_list<value_type> il);
erase iterator erase (const_iterator   position); Erase elements
size_type   erase (const key_type& k);
iterator  erase (const_iterator first, const_iterator   last);
swap void swap (map& x); Swap content
clear void clear() noexcept; Clear content 
emplace template <class...   Args>
    pair<iterator,bool> emplace (Args&&... args);
Construct and insert element
emplace_hint template <class...   Args>
    iterator emplace_hint (const_iterator position, Args&&... args);
Construct and insert element with hint 

   示例代码:

// map::insert
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap.insert ( std::pair<char,int>('a',100) );
  mymap.insert ( std::pair<char,int>('z',200) );

  std::pair<std::map<char,int>::iterator,bool> ret;
  ret = mymap.insert ( std::pair<char,int>('z',500) );
  if (ret.second==false) {
    std::cout << "element 'z' already existed";
    std::cout << " with a value of " << ret.first->second << '\n';
  }

  std::map<char,int>::iterator it = mymap.begin();
  mymap.insert (it, std::pair<char,int>('b',300));  // max efficiency inserting
  mymap.insert (it, std::pair<char,int>('c',400));  // no max efficiency inserting

  std::map<char,int> anothermap;
  anothermap.insert(mymap.begin(),mymap.find('c'));

  // showing contents:
  std::cout << "mymap contains:\n";
  for (it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  std::cout << "anothermap contains:\n";
  for (it=anothermap.begin(); it!=anothermap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
element 'z' already existed with a value of 200
mymap contains:
a => 100
b => 300
c => 400
z => 200
anothermap contains:
a => 100
b => 300
-----------------------------------------------------------------------------------------
// erasing from map
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;
  std::map<char,int>::iterator it;

  // insert some values:
  mymap['a']=10;
  mymap['b']=20;
  mymap['c']=30;
  mymap['d']=40;
  mymap['e']=50;
  mymap['f']=60;

  it=mymap.find('b');
  mymap.erase (it);                   // erasing by iterator

  mymap.erase ('c');                  // erasing by key

  it=mymap.find ('e');
  mymap.erase ( it, mymap.end() );    // erasing by range

  // show content:
  for (it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
a => 10
d => 40
-----------------------------------------------------------------------------------------
// swap maps
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> foo,bar;

  foo['x']=100;
  foo['y']=200;

  bar['a']=11;
  bar['b']=22;
  bar['c']=33;

  foo.swap(bar);

  std::cout << "foo contains:\n";
  for (std::map<char,int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  std::cout << "bar contains:\n";
  for (std::map<char,int>::iterator it=bar.begin(); it!=bar.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
foo contains:
a => 11
b => 22
c => 33
bar contains:
x => 100
y => 200
-----------------------------------------------------------------------------------------
// map::clear
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap['x']=100;
  mymap['y']=200;
  mymap['z']=300;

  std::cout << "mymap contains:\n";
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  mymap.clear();
  mymap['a']=1101;
  mymap['b']=2202;

  std::cout << "mymap contains:\n";
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
mymap contains:
x => 100
y => 200
z => 300
mymap contains:
a => 1101
b => 2202
-----------------------------------------------------------------------------------------
// map::emplace
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap.emplace('x',100);
  mymap.emplace('y',200);
  mymap.emplace('z',100);

  std::cout << "mymap contains:";
  for (auto& x: mymap)
    std::cout << " [" << x.first << ':' << x.second << ']';
  std::cout << '\n';

  return 0;
}

Output:
mymap contains: [x:100] [y:200] [z:100]
-----------------------------------------------------------------------------------------
// map::emplace_hint
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;
  auto it = mymap.end();

  it = mymap.emplace_hint(it,'b',10);
  mymap.emplace_hint(it,'a',12);
  mymap.emplace_hint(mymap.end(),'c',14);

  std::cout << "mymap contains:";
  for (auto& x: mymap)
    std::cout << " [" << x.first << ':' << x.second << ']';
  std::cout << '\n';

  return 0;
}

Output:
mymap contains: [a:12] [b:10] [c:14]
示例代码
  • Observers
函数 函数原型 功能描述
key_comp key_compare key_comp() const; Returns a copy of the comparison object used by the container to compare keys.
value_comp value_compare value_comp() const; Returns a comparison object that   can be used to compare two elements to get whether the key of the first one   goes before the second.The arguments taken by this function object are of   member type value_type (defined in map as an alias of pair<const key_type,mapped_type>),   but the mapped_type part of the value is not taken into consideration in this   comparison.

  示例代码:

// map::key_comp
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  std::map<char,int>::key_compare mycomp = mymap.key_comp();

  mymap['a']=100;
  mymap['b']=200;
  mymap['c']=300;

  std::cout << "mymap contains:\n";

  char highest = mymap.rbegin()->first;     // key value of last element

  std::map<char,int>::iterator it = mymap.begin();
  do {
    std::cout << it->first << " => " << it->second << '\n';
  } while ( mycomp((*it++).first, highest) );

  std::cout << '\n';

  return 0;
}

Output:
mymap contains:
a => 100
b => 200
c => 300
----------------------------------------------------------------------------------------
// map::value_comp
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap['x']=1001;
  mymap['y']=2002;
  mymap['z']=3003;

  std::cout << "mymap contains:\n";

  std::pair<char,int> highest = *mymap.rbegin();          // last element

  std::map<char,int>::iterator it = mymap.begin();
  do {
    std::cout << it->first << " => " << it->second << '\n';
  } while ( mymap.value_comp()(*it++, highest) );

  return 0;
}

Output:
mymap contains:
x => 1001
y => 2002
z => 3003
示例代码
  • 其他操作(Operations
函数 函数原型 功能描述
find iterator find (const key_type& k); Get iterator to element
const_iterator find (const key_type& k) const;
count size_type count (const key_type& k) const; Count   elements with a specific key, 0 or 1
lower_bound iterator lower_bound (const key_type& k); Returns an iterator pointing to the first   element in the container whose key is not considered to go before k (i.e.,   either it is equivalent or goes after).
const_iterator lower_bound (const key_type& k) const;
upper_bound iterator upper_bound (const key_type& k); Returns an iterator pointing to the first   element in the container whose key is considered to go after k.
const_iterator upper_bound (const key_type& k) const;
equal_range pair<const_iterator,const_iterator> equal_range (const key_type& k) const; Returns the bounds of a range that includes all   the elements in the container which have a key equivalent to k. Because the   elements in a map container have unique keys, the range returned will contain   a single element at most.
pair<iterator,iterator> equal_range (const key_type& k);

  示例代码:

// map::find
#include <iostream>
#include <map>

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;
}

Output:
elements in mymap:
a => 50
c => 150
d => 200
-----------------------------------------------------------------------------
// map::count
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;
  char c;

  mymap ['a']=101;
  mymap ['c']=202;
  mymap ['f']=303;

  for (c='a'; c<'h'; c++)
  {
    std::cout << c;
    if (mymap.count(c)>0)
      std::cout << " is an element of mymap.\n";
    else 
      std::cout << " is not an element of mymap.\n";
  }

  return 0;
}

Output:
a is an element of mymap.
b is not an element of mymap.
c is an element of mymap.
d is not an element of mymap.
e is not an element of mymap.
f is an element of mymap.
g is not an element of mymap.
-----------------------------------------------------------------------------
// map::lower_bound/upper_bound
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;
  std::map<char,int>::iterator itlow,itup;

  mymap['a']=20;
  mymap['b']=40;
  mymap['c']=60;
  mymap['d']=80;
  mymap['e']=100;

  itlow=mymap.lower_bound ('b');  // itlow points to b
  itup=mymap.upper_bound ('d');   // itup points to e (not d!)

  mymap.erase(itlow,itup);        // erases [itlow,itup)

  // print content:
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

Output:
a => 20
e => 100
-----------------------------------------------------------------------------
// map::equal_range
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap['a']=10;
  mymap['b']=20;
  mymap['c']=30;

  std::pair<std::map<char,int>::iterator,std::map<char,int>::iterator> ret;
  ret = mymap.equal_range('b');

  std::cout << "lower bound points to: ";
  std::cout << ret.first->first << " => " << ret.first->second << '\n';

  std::cout << "upper bound points to: ";
  std::cout << ret.second->first << " => " << ret.second->second << '\n';

  return 0;
}

Output:
lower bound points to: 'b' => 20
upper bound points to: 'c' => 30
示例代码
  • 分配器(Allocator
函数 函数原型 功能描述
get_allocator allocator_type get_allocator()   const noexcept; Get allocator

 

翻译、参考:

  http://www.cplusplus.com/reference/map/map/

posted on 2019-04-10 15:18  泣血  阅读(36055)  评论(0编辑  收藏  举报

导航