Was ich meine ist - wir wissen, dass die std::map
Elemente nach den Schlüsseln sortiert sind. Nehmen wir also an, die Schlüssel sind ganze Zahlen. Wenn ich von std::map::begin()
bis zur std::map::end()
Verwendung von a iteriere for
, garantiert der Standard, dass ich konsequent durch die Elemente mit Schlüsseln iteriere, die in aufsteigender Reihenfolge sortiert sind?
Beispiel:
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;
}
Wird dies garantiert gedruckt 234
oder ist die Implementierung definiert?
Realer Grund: Ich habe einen std::map
mit int
Schlüsseln. In sehr seltenen Situationen möchte ich alle Elemente mit einem Schlüssel durchlaufen, der größer als ein konkreter int
Wert ist. Ja, es klingt wie std::vector
die bessere Wahl, aber beachten Sie meine "sehr seltenen Situationen".
EDIT : Ich weiß, dass die Elemente von std::map
sortiert sind. Sie müssen nicht darauf hinweisen (für die meisten Antworten hier). Ich habe es sogar in meiner Frage geschrieben.
Ich habe nach den Iteratoren und der Reihenfolge gefragt, wenn ich durch einen Container iteriere. Danke @Kerrek SB für die Antwort.
quelle
map::upper_bound
den Punkt finden, an dem Sie mit der Iteration beginnen können.Antworten:
Ja, das ist garantiert. Darüber hinaus
*begin()
gibt Ihnen die kleinste und*rbegin()
das größte Element, wie durch den Vergleichsoperator bestimmt, und zwei Schlüsselwertea
undb
für die der Ausdruck!compare(a,b) && !compare(b,a)
wahr ist gleich betrachtet werden . Die Standardvergleichsfunktion iststd::less<K>
.Die Reihenfolge ist kein Glücksbonus, sondern ein grundlegender Aspekt der Datenstruktur, da die Reihenfolge verwendet wird, um zu bestimmen, wann zwei Schlüssel gleich sind (gemäß der obigen Regel) und um eine effiziente Suche durchzuführen (im Wesentlichen eine Binärdatei) Suche, die logarithmische Komplexität in der Anzahl der Elemente hat).
quelle
std::unordered_map
hat der eine effizientere Suchzeit von O (1). Der Vorteil vonstd::map
liegt in der Schlüsselreihenfolge, aber nicht in der Suche.Dies wird durch die Anforderungen an assoziative Container im C ++ - Standard garantiert. Siehe z. B. 23.2.4 / 10 in C ++ 11:
und 23.2.4 / 11
quelle
Ich denke, es gibt eine Verwirrung in den Datenstrukturen.
In den meisten Sprachen ist a
map
einfach ein AssociativeContainer: Es ordnet einen Schlüssel einem Wert zu. In den "neueren" Sprachen wird dies im Allgemeinen mithilfe einer Hash-Map erreicht, sodass keine Reihenfolge garantiert wird.In C ++ ist dies jedoch nicht so:
std::map
ist ein sortierter assoziativer Containerstd::unordered_map
ist ein auf Hash-Tabellen basierender assoziativer Container, der in C ++ 11 eingeführt wurdeAlso, um die Garantien bei der Bestellung zu klären.
In C ++ 03:
std::set
,std::multiset
,std::map
Undstd::multimap
werden entsprechend den Tasten zu bestellen garantiert (und das Kriterium geliefert)std::multiset
undstd::multimap
legt der Standard keine Bestellgarantie für äquivalente Elemente fest (dh solche, die gleich sind)In C ++ 11:
std::set
,std::multiset
,std::map
Undstd::multimap
werden entsprechend den Tasten zu bestellen garantiert (und das Kriterium geliefert)std::multiset
und schreibtstd::multimap
der Standard vor, dass äquivalente Elemente (diejenigen, die gleich sind) gemäß ihrer Einfügereihenfolge (zuerst zuerst eingefügt) geordnet sind.std::unordered_*
Container werden, wie der Name schon sagt, nicht bestellt. Am bemerkenswertesten ist die Reihenfolge der Elemente kann geändert werden, wenn der Behälter verändert wird (beim Einfügen / Löschen).Wenn der Standard besagt, dass Elemente in einer bestimmten Reihenfolge angeordnet sind, bedeutet dies:
Ich hoffe, das klärt Verwirrung.
quelle
Ja,
std::map
ist ein sortierter Behälter, der vonKey
der mitgelieferten bestellt wirdComparator
. So ist es garantiert.Das ist sicher möglich.
quelle
Ja ... die Elemente in a
std::map
haben eine strikte schwache Reihenfolge, was bedeutet, dass die Elemente aus einer Menge bestehen (dh es gibt keine Wiederholungen von Schlüsseln, die "gleich" sind), und die Gleichheit wird durch Testen einer beliebigen bestimmt zwei Schlüssel A und B: Wenn Schlüssel A nicht kleiner als Schlüssel B und B nicht kleiner als A ist, ist Schlüssel A gleich Schlüssel B.Abgesehen davon können Sie die Elemente von a nicht richtig sortieren,
std::map
wenn die schwache Reihenfolge für diesen Typ nicht eindeutig ist (in Ihrem Fall, in dem Sie Ganzzahlen als Schlüsseltyp verwenden, ist dies kein Problem). Sie müssen in der Lage sein, eine Operation zu definieren, die eine Gesamtreihenfolge für den Typ definiert, den Sie für die Schlüssel in Ihrem verwendenstd::map
. Andernfalls haben Sie nur eine Teilreihenfolge für Ihre Elemente oder Posets, deren Eigenschaft A möglicherweise nicht mit A vergleichbar ist B. In diesem Szenario können Sie normalerweise die Schlüssel / Wert-Paare einfügen. Wenn Sie jedoch die gesamte Karte durchlaufen und / oder "fehlende" Elemente erkennen, werden möglicherweise doppelte Schlüssel / Wert-Paare angezeigt. Schlüssel / Wert-Paare, wenn Sie versuchen,std::map::find()
ein bestimmtes Schlüssel / Wert-Paar in der Karte auszuführen .quelle
begin () kann das kleinste Element ergeben. Aber es hängt von der Umsetzung ab. Ist es im C ++ - Standard angegeben? Wenn nicht, ist es gefährlich, diese Annahme zu treffen.
quelle