2010-08-05 10 views
7

Ich habe eine std::list< std::pair<std::string,double> >, von der ich weiß, dass sie nach der std::string element sortiert ist.Wie man eine sortierte std :: list von std :: pair in eine std :: map konvertiert

Seit Ich mag würde eine Menge std::find_if basierend auf dem std::string Element tun, glaube ich, ein std::map<string,double,MyOwnBinaryPredicate> mit lower_bound und upper_bound würde mehr ausreichend sein.

Tatsache ist, dass ich insert Elemente in der std::map in einer effizienten Weise will. Daher möchte ich einen zusätzlichen Iterator verwenden, um die insert schneller zu machen.

Ich glaube, der einfachste Weg, ein const_reverse_iterator zu gehen durch die std::list nutzen würde und die begin() der std::map zu verwenden.

Würdest du es so machen, oder ist es eine schlechte Idee?

Danke!

+0

nicht [C++] auf den Titel setzen Sie. Dafür sind Tags da. – NullUserException

+0

Mit den Antworten von grddev und Luther Blissett habe ich ungefähr dieselben Leistungen wie bei meinem ersten Vorschlag (mit 'begin()', nicht 'end()'). Beide sind jedoch prägnant. Ich akzeptiere grddev's Antwort für seine Einfachheit, aber ich denke an den 'std :: inserter'. Danke euch allen! – Wok

Antwort

11

Wenn Sie bereits eine sortierte Liste, die Predicate nach dem Prädikat sortiert ist, können Sie nur die folgenden:

std::list< std::pair<std::string, double> > sorted_list; 
std::map<string, double, Predicate> map(sorted_list.begin(), sorted_list.end()); 

Der map Konstruktor hat lineare Zeitkomplexität, wenn Ihre Liste bereits sortiert, O (n * log n) sonst. Sie können dann direkt mit der Karte arbeiten, wie Sie es auch tun würden.

Wenn Sie später die Ergebnisse zurück in Ihre Liste wollen könnten Sie tun genau das Gegenteil:

sorted_list.assign(map.begin(), map.end());
+3

+1: Ich habe vergessen, die lineare Ctor für sortiert. Groß! –

+0

Der Vorteil dieser Antwort ist ihre Einfachheit. Vielen Dank! – Wok

4

Sie können std :: copy und std :: Inserter verwenden:

std::copy(the_list.begin(),the_list.end(),std::inserter(the_map,the_map.begin())); 

weil der Iterator für eine Liste < Paar> einen Werttyp kompatibel ist < X, Y> 's Iteratoren abzubilden.

+0

Std :: Inserter()? Nun, Sie lernen etwas neues jeden Tag :) –

+1

+1: Dies hat eine ebenso gute Leistung und funktioniert auch mit einer vorhandenen Karte – grddev

+0

verwendet 'std :: Inserter (the_map, the_map.begin())' oder 'std :: Inserter (the_map , the_map.end()) 'besser hier, da die Liste sortiert ist? – msandiford

0

Ich würde einfach auf der Liste iterieren und jedes Paar in eine Karte einfügen oder die ordentliche Methode verwenden, die Luther Blissett beschrieben hat.
Die Tatsache, dass ich nicht verstehe, was Sie versuchen zu tun, bedeutet, dass es entweder zu unlesbarem Code führt oder dass Sie weit weg sind.
Warum machst du es so?
Können Sie den Code ändern, um eine Karte an Sie anstelle einer Liste an erster Stelle zurückzugeben?

+0

Ich muss an erster Stelle eine std :: list verwenden, weil es Elemente gibt, die denselben std :: string Schlüssel haben. Dann gibt es Operationen, die mir erlauben, am Ende eine std :: map zu verwenden. Ich könnte darüber nachdenken, eine std :: map etwas früher im Prozess zu verwenden, aber die Frage ist in diesem Fall immer noch relevant. – Wok

+0

Haben Sie in Betracht gezogen, std :: multimap zu verwenden? Siehe hier: http://www.sgi.com/tech/stl/Multimap.html –

Verwandte Themen