What is the difference between std::list<std::pair> and std::map in C++ STL?
Solution 1:
std::map<X, Y>
:
- is an ordered structure with respect to keys (that is, when you iterate over it, keys will be always increasing).
- supports unique keys (
X
s) only - offers fast
find()
method (O(log n)
) which finds the Key-Value pair by Key - offers an indexing operator
map[key]
, which is also fast
std::list<std::pair<X, Y> >
:
- is a simple sequence of paired
X
s andY
s. They remain in the order you put it in. - can hold any number of duplicates
- finding a particular key in a
list
isO(N)
(no special method) - offers the
splice
method.
Solution 2:
std::pair
std::pair
is a templated tuple-structure limited to 2 items, called first and second:
std::pair<int, std::string> myPair ;
myPair.first = 42 ;
myPair.second = "Hello World" ;
std::pair
is used as a "generic container" by the STL (and other code) to aggregate two values at the same time without having to redefine yet another struct
.
std::map
std::map
is an templated associative container, associating keys and values together. The easiest (but not more efficient) example is :
std::map<int, std::string> myMap ;
myMap[42] = "Fourty Two" ;
myMap[111] = "Hello World" ;
// ...
std::string strText ; // strText is ""
strText = myMap[111] ; // strText is now "Hello World"
strText = myMap[42] ; // strText is now "Fourty Two"
strText = myMap[23] ; // strText is now "" (and myMap has
// a new value "" for key 23)
std::pair
and std::map
Note: This was the answer to the original, unedited question.
The std::map
functions needs to return iterators to the keys and values at the same time to remain efficient... So the obvious solution is to return iterators to pairs:
std::map<int, std::string> myMap ;
myMap[42] = "Fourty Two" ;
myMap[111] = "Hello World" ;
myMap.insert(std::make_pair(23, "Bye")) ;
std::map<int, std::string>::iterator it = myMap.find(42) ;
std::pair<int, std::string> keyvalue = *it ; // We assume 42 does
// exist in the map
int key = keyvalue.first ;
int value = keyvalue.second ;
std::list<std::pair<A,B> >
and std::map<A,B>
Note: Edited after edition of the question.
Thus, at first glance, a map of pairs and a list of pairs would seem the same. But this is not the case:
The map is inherently ordered by the functor provided, whereas the list will keep the pairs of [A,B] right where you put them. This makes insertion O(log n) for the map, whereas raw insertion inside a list is a constant complexity (searching where to insert it is another problem).
You can simulate somewhat the behavior of a map using a list of pairs, but note that the map is usually implemented as a tree of items, whereas the list is a chained list of items. Thus, algorithm like dichotomy will work a lot faster in a map than in a list.
Thus, finding an item in a map is O(log n), whereas in an unordered list, it is O(n). And if the list is ordered, and you want to use dichotomy, you won't get the expected performance boost, as the traversal the list of items is done item by item anyway.
(In a project I worked on one year ago, we replaced a list of ordered items by a set of the same ordered items, and it boosted the performance. The set having the same internal tree structure as the map, I guess the same boost would apply here)