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 type definition notes
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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM