Wie kopiert man_if von Karte zu Vektor?

8

Ich möchte Werte kopieren, die mit einem Prädikat (equal ints) von map<string,int> zu einem vector<int> übereinstimmen.

Das habe ich versucht:

%Vor%

Die Fehlermeldung von g ++ 4.6.1 lautet:

%Vor%

Gibt es eine Möglichkeit, das Beispiel an die obige Kopie anzupassen?

    
BЈовић 15.11.2011, 14:28
quelle

6 Antworten

12

Mit boost::range ist es so einfach wie:

%Vor%     
Mankarse 15.11.2011, 14:37
quelle
11
___ qstntxt ___

Ich möchte Werte kopieren, die mit einem Prädikat (equal ints) von map::iterator zu einem pair<string const,int> übereinstimmen.

Das habe ich versucht:

%Vor%

Die Fehlermeldung von g ++ 4.6.1 lautet:

%Vor%

Gibt es eine Möglichkeit, das Beispiel an die obige Kopie anzupassen?

    
___ answer8138023 ___

Mit vector::iterator ist es so einfach wie:

%Vor%     
___ answer8138085 ___

int erlaubt nicht die Übertragung von einem Typ zu einem anderen, nur um zu filtern, was kopiert werden soll.

Sie könnten copy_if verwenden, um den Schlüssel loszuwerden und dann for_each :

zu verwenden %Vor%

Eine einfache for-Schleife wäre jedoch effizienter und viel einfacher zu lesen.

    
___ answer8137958 ___

Ich kann nicht verstehen, warum die einfache for-loop-Lösung nicht der bevorzugte Ansatz für dieses Problem ist

%Vor%

Außer dass es den Code lesbarer macht, ist es besser. Ich habe einen einfachen Benchmark geschrieben, um zu sehen, wie sich eine for-Schleife im Vergleich zu den anderen vorgeschlagenen Lösungen verhält:

%Vor%

Die Ergebnisse, die ich erhalten habe, sind die folgenden:

%Vor%     
___ qstnhdr ___ Wie kopiert man_if von Karte zu Vektor? ___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ answer8137998 ___

Vermutlich möchten Sie nur die zugehörigen Werte von push_back abrufen, nicht die Schlüssel.

Die SGI-Version von STL hat %code% und %code% Iteratoren für diese Art von Aufgabe.

Ich persönlich glaube jedoch nicht, dass dies wirklich mit einer Kopie geschehen sollte - Sie transformieren die Daten, kopieren sie nicht. Daher würde ich empfehlen, %code% mit einem Funktor zu verwenden, um das zweite Element des Paares zurückzugeben.

    
___ tag123c11 ___ C ++ 11 ist eine 2011 verabschiedete Version des C ++ - Sprachstandards. Sie hat viele Änderungen und Ergänzungen in der Kernsprache sowie der verbesserten und erweiterten C ++ - Standardbibliothek vorgenommen. ___ tag123copy ___ Zum Kopieren wird ein Duplikat eines Objekts erstellt, ohne das Original zu zerstören. Häufig in Text-Editoren angezeigt, mit denen Sie Text kopieren und an anderer Stelle einfügen können. ___ answer8138307 ___

Der Compiler-Fehler ist eigentlich ziemlich knapp:

%Vor%

Und genau das ist das Problem. Das %code% , von dem du kopierst, hat Iteratoren, die auf ein %code% dereferenzieren, und es gibt keine Möglichkeit, implizit ein %code% auf nur ein %code% zu transformieren.

Aus diesem Grund können Sie %code% oder %code% nicht verwenden, um von einem %code% in ein %code% zu kopieren; aber die Standardbibliothek stellt einen Algorithmus zur Verfügung, den Sie verwenden können, kreativ genannt %code% . %code% ist sehr ähnlich zu %code% , da zwei Quell-Iteratoren und ein Ziel-Iterator benötigt werden. Der Unterschied ist %code% nimmt auch eine unäre Funktion, die die eigentliche Transformation durchführt. Mit einem C ++ 11 Lambda können Sie den gesamten Inhalt eines %code% in ein %code% wie folgt kopieren:

%Vor%

Was ist, wenn Sie nicht den gesamten Inhalt von %code% kopieren möchten, sondern nur einige Elemente, die die certian Kriterien erfüllen? Einfach, verwenden Sie einfach %code% .

Was ist das, sagst du? Es gibt keine %code% in der Standardbibliothek? Nun ja, du hast da einen Punkt. Frustrierend gibt es keine %code% in der Standardbibliothek. Allerdings Schreiben eines ist eine einfache Aufgabe. Hier ist der Code:

%Vor%

Wie Sie vielleicht denken, ist die Verwendung von %code% so, als würde Sie %code% übernehmen und zusammen mit %code% zusammenfügen. Hier ist ein Beispiel für einen Pseudo-Code:

%Vor%     
___
Kleist 15.11.2011 14:32
quelle
5

Der Compiler-Fehler ist eigentlich ziemlich knapp:

%Vor%

Und genau das ist das Problem. Das map , von dem du kopierst, hat Iteratoren, die auf ein pair<KEY,VALUE> dereferenzieren, und es gibt keine Möglichkeit, implizit ein pair<KEY,VALUE> auf nur ein VALUE zu transformieren.

Aus diesem Grund können Sie copy oder copy_if nicht verwenden, um von einem map in ein vector zu kopieren; aber die Standardbibliothek stellt einen Algorithmus zur Verfügung, den Sie verwenden können, kreativ genannt transform . transform ist sehr ähnlich zu copy , da zwei Quell-Iteratoren und ein Ziel-Iterator benötigt werden. Der Unterschied ist transform nimmt auch eine unäre Funktion, die die eigentliche Transformation durchführt. Mit einem C ++ 11 Lambda können Sie den gesamten Inhalt eines map in ein vector wie folgt kopieren:

%Vor%

Was ist, wenn Sie nicht den gesamten Inhalt von map kopieren möchten, sondern nur einige Elemente, die die certian Kriterien erfüllen? Einfach, verwenden Sie einfach transform_if .

Was ist das, sagst du? Es gibt keine transform_if in der Standardbibliothek? Nun ja, du hast da einen Punkt. Frustrierend gibt es keine transform_if in der Standardbibliothek. Allerdings Schreiben eines ist eine einfache Aufgabe. Hier ist der Code:

%Vor%

Wie Sie vielleicht denken, ist die Verwendung von transform_if so, als würde Sie copy_if übernehmen und zusammen mit transform zusammenfügen. Hier ist ein Beispiel für einen Pseudo-Code:

%Vor%     
John Dibling 15.11.2011 14:58
quelle
2

std::copy_if erlaubt nicht die Übertragung von einem Typ zu einem anderen, nur um zu filtern, was kopiert werden soll.

Sie könnten std::transform verwenden, um den Schlüssel loszuwerden und dann std::remove_if :

zu verwenden %Vor%

Eine einfache for-Schleife wäre jedoch effizienter und viel einfacher zu lesen.

    
larsmoa 15.11.2011 14:41
quelle
2

Ich kann nicht verstehen, warum die einfache for-loop-Lösung nicht der bevorzugte Ansatz für dieses Problem ist

%Vor%

Außer dass es den Code lesbarer macht, ist es besser. Ich habe einen einfachen Benchmark geschrieben, um zu sehen, wie sich eine for-Schleife im Vergleich zu den anderen vorgeschlagenen Lösungen verhält:

%Vor%

Die Ergebnisse, die ich erhalten habe, sind die folgenden:

%Vor%     
pnezis 15.11.2011 14:33
quelle
0

Vermutlich möchten Sie nur die zugehörigen Werte von map abrufen, nicht die Schlüssel.

Die SGI-Version von STL hat select1st und select2nd Iteratoren für diese Art von Aufgabe.

Ich persönlich glaube jedoch nicht, dass dies wirklich mit einer Kopie geschehen sollte - Sie transformieren die Daten, kopieren sie nicht. Daher würde ich empfehlen, std::transform mit einem Funktor zu verwenden, um das zweite Element des Paares zurückzugeben.

    
Jerry Coffin 15.11.2011 14:36
quelle

Tags und Links