Ce que je veux dire, c'est - nous savons que les std::map
éléments de s sont triés en fonction des clés. Donc, disons que les clés sont des entiers. Si j'itère de std::map::begin()
à en std::map::end()
utilisant a for
, la norme garantit-elle que je vais itérer en conséquence à travers les éléments avec des clés, triés par ordre croissant?
Exemple:
std::map<int, int> map_;
map_[1] = 2;
map_[2] = 3;
map_[3] = 4;
for( std::map<int, int>::iterator iter = map_.begin();
iter != map_.end();
++iter )
{
std::cout << iter->second;
}
L'impression 234
est-elle garantie ou est-ce une implémentation définie?
Raison réelle: j'ai une clé std::map
avec int
. Dans de très rares situations, j'aimerais parcourir tous les éléments, avec une clé, supérieure à une int
valeur concrète . Oui, il semble que ce std::vector
serait le meilleur choix, mais remarquez mes "situations très rares".
EDIT : Je sais, que les éléments de std::map
sont triés .. pas besoin de le signaler (pour la plupart des réponses ici). Je l'ai même écrit dans ma question.
Je posais des questions sur les itérateurs et l'ordre lorsque je parcourais un conteneur. Merci @Kerrek SB pour la réponse.
la source
map::upper_bound
pour trouver le point de départ de l'itération.Réponses:
Oui, c'est garanti. De plus,
*begin()
vous donne le plus petit et*rbegin()
le plus grand élément, comme déterminé par l'opérateur de comparaison, et deux valeurs clésa
etb
pour lesquelles l'expression!compare(a,b) && !compare(b,a)
est vraie sont considérées comme égales. La fonction de comparaison par défaut eststd::less<K>
.L'ordre n'est pas un bonus chanceux, mais plutôt un aspect fondamental de la structure de données, car l'ordre est utilisé pour déterminer quand deux clés sont identiques (par la règle ci-dessus) et pour effectuer une recherche efficace (essentiellement un binaire recherche, qui a une complexité logarithmique dans le nombre d'éléments).
la source
std::unordered_map
a un temps de recherche plus efficace de O (1). L'avantage destd::map
réside dans l'ordre des clés, mais pas dans la recherche.Ceci est garanti par les exigences de conteneur associatif dans la norme C ++. Par exemple, voir 23.2.4 / 10 en C ++ 11:
et 23.2.4 / 11
la source
Je pense qu'il y a une confusion dans les structures de données.
Dans la plupart des langues, a
map
est simplement un AssociativeContainer: il mappe une clé à une valeur. Dans les langues "plus récentes", ceci est généralement réalisé en utilisant une carte de hachage, donc aucun ordre n'est garanti.En C ++, cependant, ce n'est pas le cas:
std::map
est un conteneur associatif triéstd::unordered_map
est un conteneur associatif basé sur une table de hachage introduit dans C ++ 11Donc, afin de clarifier les garanties à la commande.
En C ++ 03:
std::set
,std::multiset
,std::map
Etstd::multimap
sont garantis d'être commandé en fonction des touches (et le critère fourni)std::multiset
etstd::multimap
, la norme n'impose aucune garantie d'ordre sur les éléments équivalents (c'est-à-dire ceux qui se comparent égaux)En C ++ 11:
std::set
,std::multiset
,std::map
Etstd::multimap
sont garantis d'être commandé en fonction des touches (et le critère fourni)std::multiset
etstd::multimap
, la norme impose que les éléments équivalents (ceux qui se comparent égaux) soient ordonnés selon leur ordre d'insertion (insérés en premier)std::unordered_*
les conteneurs ne sont, comme leur nom l'indique, pas ordonnés. Plus particulièrement, l'ordre des éléments peut changer lorsque le conteneur est modifié (lors de l'insertion / suppression).Lorsque la norme dit que les éléments sont ordonnés d'une certaine manière, cela signifie que:
J'espère que cela dissipe toute confusion.
la source
Oui,
std::map
est un conteneur trié, commandé par leKey
avec le fourniComparator
. C'est donc garanti.C'est sûrement possible.
la source
Oui ... les éléments de a
std::map
ont un ordre faible strict, ce qui signifie que les éléments seront composés d'un ensemble (c'est-à-dire qu'il n'y aura pas de répétition de clés "égales"), et l'égalité est déterminée en testant sur tout deux clés A et B, que si la clé A n'est pas inférieure à la clé B, et B n'est pas inférieure à A, alors la clé A est égale à la clé B.Cela étant dit, vous ne pouvez pas trier correctement les éléments de a
std::map
si l'ordre faible pour ce type est ambigu (dans votre cas, où vous utilisez des entiers comme type de clé, ce n'est pas un problème). Vous devez être capable de définir une opération qui définit un ordre total sur le type que vous utilisez pour les clés de votrestd::map
, sinon vous n'aurez qu'un ordre partiel pour vos éléments, ou poset, qui a une propriété où A peut ne pas être comparable à B. Ce qui se passera généralement dans ce scénario, c'est que vous serez en mesure d'insérer les paires clé / valeur, mais vous risquez de vous retrouver avec des paires clé / valeur en double si vous parcourez toute la carte et / ou détectez «manquant» paires clé / valeur lorsque vous essayez d'effectuer unestd::map::find()
paire clé / valeur spécifique dans la carte.la source
begin () peut donner le plus petit élément. Mais c'est la mise en œuvre qui dépend. Est-il spécifié dans la norme C ++? Sinon, il est dangereux de faire cette hypothèse.
la source