STL之map
参见http://www.cplusplus.com/reference/map/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;Maps are associative containers that store elements formed by a combination of a key value and a mapped value, following a specific order.
[map是关联容器,其元素是键值对的形式,且元素是根据指定的排序方式进行排列的]
In a map, the key values are generally used to sort and uniquely identify the elements, while the mapped values store the content associated to this key. The types of key and mapped value may differ, and are grouped together in member type value_type, which is a pair type combining both:
[在map 中,key value一般被用来对元素进行排序以及唯一确定元素,而mapped value则用来存储对应key value所关联的内容。key value和mapped value的数据类型可能不一样,但它们都是通过成员类型value_type组织起来的,value_type是一个pair类型,其定义如下:]
typedef pair<const Key, T> value_type;[即map的元素是pair对象,因此取得map元素之后,我们需要通过first和second来获取其key_value和mapped_value]
Internally, the elements in a map are always sorted by its key following a specific strict weak ordering criterion indicated by its internal comparison object (of type Compare).
[map的内部实现中,元素总是根据key value来进行排序的,排序是通过内部的比较对象(internal comparison object)进行严格弱化排序]
Maps are typically implemented as binary search trees.
[map的典型实现是通过二进制搜索树]
pair包含在头文件utility中,是个结构体模板,其定义如下:
template<class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(); //Constructs a pair object with its elements value-initialized.
pair(const T1 &x,const T2 &y); //Member first is constructed with x and member second with y.
template<class V,class W>
pair(const pair<V,W> &pr); //The object is initialized with the contents of the pr pair object.
};对于Constructs a pair object with its elements value-initialized.这种构造方式,我们可以通过make_pair()来对其成员first和
second进行赋值,make_pair()是个函数模板,其定义如下:
template <class T1, class T2>
pair<V1,V2> make_pair (T1&& x, T2&& y); // see below for definition of V1 and V2Construct pair object
[make_pair()是用来构造pair对象的]
Constructs a pair object with its first element set to x and its second element set to y.
[构造一个pair类对象并将赋值其成员first为x,second为y]
The template types can be implicitly deduced from the arguments passed to make_pair.
[模板参数可以通过传递给make_pair()的实参被隐式地推导出来]
pair objects can be constructed from other pair objects containing different types, if the respective types are implicitly convertible.
[如果各自的模板参数类型可以隐式转换,则一个pair对象可以通过其他pair对象构造出来]
从map的定义可以看到,map的默认比较对象是less<Key>的对象
template<class T> struct less;
Function object class for less-than inequality comparison
[less是用于小于比较的函数对象类]
Binary function object class whose call returns whether the its first argument compares less than the second (as returned by operator <).
[二元函数对象类less返回第一个参数是否小于第二个参数,如同operator<那样]
Generically, function objects are instances of a class with member function operator() defined. This member function allows the object to be used with the same syntax as a function call.
[通常情况下,函数对象是一个定义了operator()函数的类的实例]
It is defined with the same behavior as:
[该类定义如下:]
template <class T> struct less {
bool operator() (const T& x, const T& y) const {return x<y;}
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
// pair::pair example #include <utility> // std::pair, std::make_pair #include <string> // std::string #include <iostream> // std::cout int main () { std::pair <std::string,double> product1; // default constructor std::pair <std::string,double> product2 ("tomatoes",2.30); // value init std::pair <std::string,double> product3 (product2); // copy constructor product1 = std::make_pair(std::string("lightbulbs"),0.99); // using make_pair (move) /* std::make_pair(std::string("lightbulbs"),0.99); 中模板参数是被隐式推导出来的,我们也可以显示写为 std::make_pair<std:string, double>(std::string("lightbulbs"),0.99); */ product2.first = "shoes"; // the type of first is string product2.second = 39.90; // the type of second is double std::cout << "The price of " << product1.first << " is $" << product1.second << '\n'; std::cout << "The price of " << product2.first << " is $" << product2.second << '\n'; std::cout << "The price of " << product3.first << " is $" << product3.second << '\n'; system("pause"); return 0; }
/* //constructing map map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type()); map (const map& x); */#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
fourth['a'] =30;
fourth['b']=40;
fourth['c']=50;
fourth['d']=70;
std::cout<<"fouth contains:\n";
for(std::map<char, int, classcomp>::iterator it = fourth.begin(); it != fourth.end(); ++it)
std::cout<<it->first<<"=>"<<it->second<<std::endl;
bool(*fn_pt)(char,char) = fncomp;
std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare
fifth['a']=30;
fifth['b']=40;
fifth['c']=50;
fifth['d']=70;
std::cout<<"\nfifth contains:\n";
for(std::map<char, int, bool(*)(char, char)>::iterator it = fifth.begin(); it != fifth.end(); ++it)
std::cout<<it->first<<"=>"<<it->second<<std::endl;
system("pause");
return 0;
}
/* iterator begin(); //返回指向第一个元素的迭代器 iterator end() //返回指向最后一个元素的下一位(past-to-end)的迭代器 reverse_iterator rbegin(); //返回指向最后一个元素的逆向迭代器 reverse_iterator rend(); //返回指向第一个元素的前一位(right before the first element)的逆向迭代器 bool empty(); //判断容器是否为空 void clear(); //删除所有元素 size_type size(); //返回容器中元素的个数 void swap(map& x); //交换两个map operator=(const map& x); iterator find(const key_type& k); //查找指定key value size_type count(const key_type& k)const; //查找容器中与k相等的元素个数(由于map容器中元素的key value唯一,因此该函数只会返回0或1) //insert pair<iterator,bool> insert(const value_type &val) iterator insert(iterator position, const value_type &val) void insert(InputIterator fist,InputIterator last) Insert elements Extends the container by inserting new elements, effectively increasing the container size by the number of elements inserted. [通过插入的元素来有效地增加容器大小] Because element keys in a map are unique, the insertion operation checks whether each inserted element has a key equivalent to the one of an element already in the container, and if so, the element is not inserted, returning an iterator to this existing element (if the function returns a value). [因为map中元素的key value是唯一的,不允许重复,因此插入操作会检查插入的元素的key value是否重复,如果重复则不进行插入,而是返回map中指向该重复元素的迭代器(如果函数有返回值的话)] For a similar container allowing for duplicate elements, see multimap. [如果想要进行重复元素的插入,请看multimap] An alternative way to insert elements in a map is by using member function map::operator[]. [在map中插入元素的另一种方法是用函数map::operator[]] Internally, map containers keep all their elements sorted by their key following the criterion specified by its comparison object. The elements are always inserted in its respective position following this ordering. [在内部实现中,map容器会用比较对象(comparison object)根据key value将元素进行排序,因此插入操作也是根据这一点插入到相对位置] Return value The single element versions (1) return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element with an equivalent key in the map. The pair::second element in the pair is set to true if a new element was inserted or false if an equivalent key already existed. [第一种插入方式返回一个pair,pair中的成员first是一个指向插入元素的迭代器或者是指向map中与插入元素的key value相等的元素的迭代器;如果插入成功,则pair的成员second为true,否则为false] The versions with a hint (2) return an iterator pointing to either the newly inserted element or to the element that already had an equivalent key in the map. [第二种插入方式返回一个指向插入元素的迭代器或者指向map中与插入元素的key value相等的元素的迭代器] Member type iterator is a bidirectional iterator type that points to elements. [map中的iterator是一个双向迭代器] 注: position Hint for the position where the element can be inserted. [position的作用是建议元素被插入的位置] The function optimizes its insertion time if position points to the element that will precede the inserted element. [如果position对应的元素在插入元素之前的话,该函数会优化插入时间] Notice that this is just a hint and does not force the new element to be inserted at that position within the map container (the elements in a map always follow a specific order depending on their key). [要注意的是,position只是建议元素的插入位置,而不是强制,另外,map中的元素会根据前面所述方法进行排序] */ #include <iostream> #include <map> int main () { std::map<char,int> mymap; // first insert function version (single parameter): 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'; } // second insert function version (with hint position): 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 // third insert function version (range insertion): 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'; system("pause"); return 0; }
/* iterator earse(const_iterator position) size_type erase(const key_type &k) iterator earse(const_iterator first,const_iterator last) Return value For the key-based version (2), the function returns the number of elements erased, which in map containers is at most 1. [第二种删除方式返回的是被删除的元素个数,至多为1] Member type size_type is an unsigned integral type. The other versions return an iterator to the element that follows the last element removed (or map::end, if the last element was removed). [其他删除方式返回的是指向最后一个被删除元素的下一个元素的迭代器] */ // 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'; system("pause"); return 0; }
/* iterator lower_bound(const key_type &k) //返回键值>=k的第一个元素的位置 iterate upper_bound(const key_type &k) //返回键值>k的第一个元素的位置 Return iterator to lower bound 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). [返回一个指向容器中第一个key value不在k之前的元素的迭代器(即指向元素的key value等于或大于k)] The function uses its internal comparison object (key_comp) to determine this, returning an iterator to the first element for which key_comp(element_key,k) would return false. [该函数利用内部的比较对象来比较,返回的迭代器指向的是第一个使得key_comp(element_key, k)返回false的元素] If the map class is instantiated with the default comparison type (less), the function returns an iterator to the first element whose key is not less than k. [如果map类的实例化使用的是默认的比较类型(less), 则该函数返回的迭代器指向的是第一个key value不小于(即大于等于)k的元素] A similar member function, upper_bound, has the same behavior as lower_bound, except in the case that the map contains an element with a key equivalent to k: In this case, lower_bound returns an iterator pointing to that element, whereas upper_bound returns an iterator pointing to the next element. [upper_bound函数的行为与lower_bound相同,只不过upper_bound返回的迭代指向的是第一个key value大于k的元素] */ #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'; system("pause"); return 0; }
/* key_compare key_comp() const; Return key comparison object Returns a copy of the comparison object used by the container to compare keys. [返回容器中被用来比较key的比较对象的拷贝] The comparison object of a map object is set on construction. Its type (member key_compare) is the third template parameter of the map template. By default, this is a less object, which returns the same as operator<. [map对象中的比较对象是在构造对象时设置的,它的类型(即成员key_compare,它是Compare的别名)是map类模板的第三个模板参数,默认情况下是一个less对象,该对象返回的结果如同operator<] This object determines the order of the elements in the container: it is a function pointer or a function object that takes two arguments of the same type as the element keys, and returns true if the first argument is considered to go before the second in the strict weak ordering it defines, and false otherwise. [比较对象决定了容器中元素的排序,比较对象是一个函数指针或者一个函数对象,该函数指针或者函数对象有两个相同类型的参数,如果按照严格弱排序,第一个参数排在第二个参数之前则返回true,否则返回false] Two keys are considered equivalent if key_comp returns false reflexively (i.e., no matter the order in which the keys are passed as arguments). [如果key_comp()返回false则认为这两个key是相等的] */ // 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) ); system("pause"); return 0; }
注: key_comp()返回值是比较对象(comparison object)的拷贝,返回值的类型是key_compare。key_compare是map的第三个模板参数Compare的别名,默认情况下是less<key_type> template<class T> struct less; Function object class for less-than inequality comparison [less是用于小于比较的函数对象类] Binary function object class whose call returns whether the its first argument compares less than the second (as returned by operator <). [二元函数对象类less返回第一个参数是否小于第二个参数,如同operator<那样] Generically, function objects are instances of a class with member function operator() defined. This member function allows the object to be used with the same syntax as a function call. [通常情况下,函数对象是一个定义了operator()函数的类的实例] It is defined with the same behavior as: [该类定义如下:] template <class T> struct less { bool operator() (const T& x, const T& y) const {return x<y;} typedef T first_argument_type; typedef T second_argument_type; typedef bool result_type; };
/* value_compare value_comp() const; Return value comparison object 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. [该函数的参数类型是value_type(其被定义为pair<const key_type, mapped_type>的别名),但mapped_type部分的值不会参与比较(也就是说参与比较的只有key value)] */ // 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) ); system("pause"); return 0; }
/* pair<iterator, iterator> equal_range(const key_type& k); Get range of equal elements Returns the bounds of a range that includes all the elements in the container which have a key equivalent to k. [返回包含所有与k相等的元素的区间] Because the elements in a map container have unique keys, the range returned will contain a single element at most. [由于map容器中元素的key value唯一,因此该函数返回的区间最多只会包含一个元素] If no matches are found, the range returned has a length of zero, with both iterators pointing to the first element that has a key considered to go after k according to the container's internal comparison object (key_comp). [如果没有匹配元素,该区间长度为0,且两个迭代器都会指向容器中第一个大于k的元素] Return value The function returns a pair, whose member pair::first is the lower bound of the range (the same as lower_bound), and pair::second is the upper bound (the same as upper_bound). [该函数返回一个pair,其中first指的是区间的lower bound,second指的是区间的upper bound] */ // 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'; system("pause"); return 0; }
/* mapped_type& operator[] (const key_type& k); Access element If k matches the key of an element in the container, the function returns a reference to its mapped value. [如果容器中已经存在key value等于k的元素,则返回该元素对应的mapped value的引用] If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor). [如果容器中不存在key value等于k的元素,则插入一个key value为k的元素并返回对应的mapped value的引用。值得注意的是这种情况下总是会将容器长度增加1,即使没有给该元素分配mapped value(该元素会利用默认的构造函数进行构造)] 注: 以上说明,在map中用insert和operator[]插入重复元素时,表现会不一致。对于insert,插入重复元素会插入失败;对于operator[],插入重复元素会修改元素的mapped value */ #include <iostream> #include <map> int main() { std::map<char, int> mymap; mymap.insert(std::pair<char, int>('b', 4)); std::pair<std::map<char, int>::iterator, bool> insert_pair; insert_pair = mymap.insert(std::make_pair<char, int>('b', 6)); //Insert failure if(insert_pair.second) std::cout<<"Insert successfully"<<std::endl; else std::cout<<"Insert failure"<<std::endl; //第二次会覆盖第一次 mymap['x'] = 8; mymap['x'] = 10; std::map<char,int>::iterator it; for(it=mymap.begin();it!=mymap.end();++it) std::cout<<it->first<<" => "<<it->second<<std::endl; system("pause"); return 0; }
/* map中默认的比较对象是less<Key>的对象,less定义如下:
template<class T> struct less{
bool operator() (const T& x, const T& y) const(return x<y;)
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
如果map的key是个结构体或者类,涉及到排序时就会出现问题,因此此时operator()中的参数x和y都是结构体或类,因此return x<y;需要我们重载operator<
注:重载的形式是形如bool operator<(const...)const,因为原始模板是这样定义的 */ #include <iostream> #include <map> #include <string> using namespace std; struct StudentInfo { int nID; string strName; bool operator<(const StudentInfo &r) const {//指定排序规则--按nID排序,如果nID相同,按strName排序 if(nID<r.nID) return true; else if(nID==r.nID) return strName.compare(r.strName)<0; else return false; } }; int main() { map<StudentInfo,int> mymap; StudentInfo studentinfo; studentinfo.nID=2; studentinfo.strName="student_one"; mymap.insert(pair<StudentInfo,int>(studentinfo,90)); studentinfo.nID=1; studentinfo.strName="student_two"; mymap.insert(pair<StudentInfo,int>(studentinfo,80)); studentinfo.nID=2; studentinfo.strName="student_three"; mymap.insert(pair<StudentInfo,int>(studentinfo, 100)); //按照指定的规则,会先输出student_two,再输出student_one map<StudentInfo,int>::iterator p=mymap.begin(); for(; p!=mymap.end(); ++p) cout<<p->first.nID<<":"<<p->first.strName<<":"<<p->second<<"\n"; system("pause"); return 0; }