Wie konstruiere ich einen std :: string aus einem std :: vectorstring?

8

Ich möchte ein std::string von einem std::vector<std::string> erstellen.

Ich könnte std::stringsteam verwenden, aber stell dir vor, es gibt einen kürzeren Weg:

%Vor%

Wie sonst könnte ich das tun?

    
WilliamKF 11.03.2013, 19:39
quelle

7 Antworten

25

Sie können die std::accumulate() Standardfunktion aus dem Header <numeric> verwenden (funktioniert, weil Eine Überladung von operator + ist für string s definiert, die die Verkettung ihrer zwei Argumente zurückgibt):

%Vor%

Alternativ können Sie einen effizienteren, kleinen for -Zyklus verwenden:

%Vor%     
Andy Prowl 11.03.2013, 19:43
quelle
34

Das ist so einfach, dass es mich erstaunt, wie viele kluge Leute es vermasselt haben.

C ++ 03:

%Vor%

C ++ 11: (die MSVC2010-Teilmenge)

%Vor%

C ++ 11:

%Vor%

Verwenden Sie nicht std::accumulate für String-Verkettung , es ist ein klassischer Schlemiel der Maler Algorithmus , sogar schlechter als das übliche Beispiel, das strcat in C verwendet. Ohne die C ++ 11-Verschiebungssemantik entstehen für jedes Element des Vektors zwei unnötige Kopien des Akkumulators. Selbst mit der Bewegungssemantik wird immer noch eine unnötige Kopie des Akkumulators für jedes Element benötigt.

Die drei obigen Beispiele sind O (n) .

std::accumulate ist O (n ^ 2) für Strings.

Sie könnten std::accumulate O (n) für Strings angeben, indem Sie einen benutzerdefinierten Funktor angeben:

%Vor%

Beachten Sie, dass s eine Referenz auf nicht-const sein muss, der Lambda-Rückgabetyp muss eine Referenz sein (daher decltype(auto) ) und der Body muss += nicht + verwenden.

    
Oktalist 09.09.2013 17:30
quelle
7

Warum benutzen Sie nicht einfach den Operator +, um sie zusammenzufügen?

%Vor%

std :: accumulate verwendet std :: plus standardmäßig unter der Haube, und das Hinzufügen von zwei Strings ist eine Verkettung in C ++, da der Operator + für std :: string überladen ist.

    
bstamour 11.03.2013 19:43
quelle
3

Meine persönliche Wahl wäre die bereichsbasierte for-Schleife, wie in Oktalists Antwort .

Boost bietet auch eine schöne Lösung:

%Vor%

Dies druckt:

  

zuerst, Sekunde

Auf jeden Fall finde ich den std::accumulate() einen Missbrauch dieses Algorithmus (ungeachtet der Komplexitätsprobleme).

    
Ali 17.05.2014 17:44
quelle
2

Ein bisschen spät auf die Party, aber ich mochte die Tatsache, dass wir Initialisierungslisten verwenden können:

%Vor%

Dann können Sie einfach (Python-Stil) aufrufen:

%Vor%     
Benjamin K. 23.07.2015 11:18
quelle
0

Mit c ++ 11 ist der stringstream Weg nicht zu gruselig:

%Vor%     
PSIAlt 11.03.2013 20:22
quelle
0

Google Abseil hat die Funktion absl :: StrJoin, die das tut, was Sie brauchen.

Beispiel aus ihrer Kopfzeile . Beachten Sie, dass das Trennzeichen auch ""

sein kann %Vor%     
NoSenseEtAl 13.12.2017 03:04
quelle