Pouvez-vous me dire la différence entre std :: list <std :: pair> et std :: map. Puis-je également utiliser la méthode find sur la liste?
Je vous remercie.
- Clarification
Question modifiée pour être plus claire.
std::map<X, Y>
:
X
s) uniquementfind()
(O(log n)
) qui trouve la paire valeur-clé par clémap[key]
, qui est également rapidestd::list<std::pair<X, Y> >
:
X
s et Y
s appariés. Ils restent dans l'ordre dans lequel vous les avez placés.list
est O(N)
(pas de méthode spéciale)splice
.std::pair
std::pair
est une structure de tuple modélisée limitée à 2 éléments, appelée premier et deuxième:
std::pair<int, std::string> myPair ;
myPair.first = 42 ;
myPair.second = "Hello World" ;
std::pair
est utilisé comme "conteneur générique" par la STL (et un autre code) pour agréger deux valeurs en même temps sans avoir à redéfinir un autre struct
.
std::map
std::map
est un conteneur associatif basé sur un modèle, associant des clés et des valeurs ensemble. L'exemple le plus simple (mais pas plus efficace) est:
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
et std::map
Remarque: Il s'agit de la réponse à la question d'origine non modifiée.
Le std::map
les fonctions doivent retourner les itérateurs aux clés et aux valeurs en même temps pour rester efficaces ... La solution évidente est donc de retourner les itérateurs aux paires:
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> >
et std::map<A,B>
Remarque: modifié après l'édition de la question.
Ainsi, à première vue, une carte de paires et une liste de paires semblent identiques. Mais ce n'est pas le cas:
La carte est intrinsèquement ordonnée par le foncteur fourni, tandis que la liste gardera les paires de [A, B] là où vous les avez placées. Cela rend l'insertion O (log n) pour la carte, tandis que l'insertion brute à l'intérieur d'une liste est une complexité constante (chercher où l'insérer est un autre problème).
Vous pouvez simuler quelque peu le comportement d'une carte à l'aide d'une liste de paires, mais notez que la carte est généralement implémentée comme une arborescence d'éléments, tandis que la liste est une liste chaînée d'éléments. Ainsi, un algorithme comme la dichotomie fonctionnera beaucoup plus rapidement dans une carte que dans une liste.
Ainsi, trouver un élément dans une carte est O (log n), alors que dans une liste non ordonnée, c'est O (n). Et si la liste est ordonnée et que vous souhaitez utiliser la dichotomie, vous n'obtiendrez pas l'augmentation de performance attendue, car la traversée de la liste des éléments est effectuée élément par élément de toute façon.
(Dans un projet sur lequel j'ai travaillé il y a un an, nous avons remplacé une liste d'articles commandés par un ensemble des mêmes articles commandés, et cela a amélioré les performances. L'ensemble ayant la même arborescence interne que la carte, je suppose que le même boost s'appliquerait ici)
(Modifié après clarification)
std::map
Est optimisé pour une recherche rapide. Il possède sa propre méthode find
qui utilise sa structure interne pour fournir de bonnes performances. En général, il inspectera uniquement les touches log(N)
, où N est le nombre d'éléments dans la carte.
std::list<std::pair>
Est une simple liste chaînée, et ne prend donc en charge que la traversée élément par élément. Vous pourriez utiliser l'algorithme std::find
Séparé ou std::find_if
Avec un prédicat personnalisé qui examine uniquement le membre first
pour mieux correspondre à la sémantique de std::map::find
, Mais ce serait très lent. En fait, il devra regarder chaque paire dans la liste pour toute recherche ayant échoué, et en regarder la moitié en moyenne pour toute recherche réussie.
std:pair
contient exactement deux objets. std:map
contient une collection d'objets appariés.
Vous ne pouvez pas utiliser find () sur une paire, car il n'y a rien à trouver. L'objet que vous voulez est soit pair.First
ou pair.Second
MISE À JOUR: En supposant que vous vouliez dire la différence entre map<>
et list<pair<> >
: La carte doit être implémentée pour une recherche rapide sur le membre key
. list
a juste une simple liste linéaire. La recherche d'un élément dans une liste nécessite de parcourir toute la liste. Cependant, std :: find () fonctionnera sur les deux.
Les cartes STL sont des tableaux associatifs, généralement implémentés en tant que hashmaps à l'intérieur. Si vous souhaitez obtenir une itération sur une carte STL, elle renverra une paire STL.
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<string, int> myMap;
myMap["myKey"] = 1337;
map<string, int>::iterator myIterator = myMap.begin();
pair<string, int> myPair = *myIterator;
cout<<"the key \""<<myPair.first<<"\" maps to the value of "<<myPair.second<<endl;
cout<<"the key \"myKey"\" maps to the value of "<<myMap["myKey"]<<endl;
return 0;
}
Je suggérerais de googler et de lire la référence complète de l'API STL car STL (à l'exception du stockage des booléens dans des vecteurs et autres bizarreries comme ça) implémente beaucoup de fonctionnalités de structure de données que vous voudriez utiliser dans n'importe quel programme sans réinventer la roue.
La carte peut fournir le meilleur temps de recherche dans la plage de O (log n), tandis que la liste peut avoir le temps de recherche de O (n).
std :: pair sert uniquement à regrouper exactement 2 objets (par exemple, "les coordonnées sur une page" sont composées de X et Y).
std :: map est un mappage d'un ensemble d'objets à un autre.
Il ne sert à rien d'essayer d'utiliser une méthode de recherche sur une paire, comme à quoi sert de trouver quelque chose dans une liste de deux choses dont vous connaissez l'ordre, même si cette méthode de recherche existait dans une classe de paires, ce qu'elle ne fait pas.
Cependant, vous POUVEZ utiliser std :: pair comme valeur de carte si c'est ce que vous voulez.