2009-12-31 5 views
20

J'ai lu Accelerated C++ et je dois dire que c'est un livre intéressant.Combinaison d'un vecteur de chaînes

Dans le chapitre 6, je dois utiliser une fonction de <algorithme> à concaténer d'un vecteur < chaîne > en une seule chaîne. Je pourrais utiliser accumulate, mais cela n'aide pas parce que les conteneurs de chaînes ne peuvent que pousser les caractères.

int main() { 
    using namespace std; 
    string str = "Hello, world!"; 
    vector<string> vec (10, str); 
    // Concatenate here? 

    return 0; 
} 

Comment joindre les chaînes ensemble?

+0

Que demandez-vous? – tster

Répondre

48

En supposant qu'il est question 6.8, il ne dit pas que vous devez utiliser accumuler - il dit utiliser "un algorithme de bibliothèque". Cependant, vous pouvez utiliser Accumulez:

#include <numeric> 

int main() { 
    string str = "Hello World!"; 
    vector<string> vec(10,str); 
    string a = accumulate(vec.begin(), vec.end(), string("")); 
    cout << a << endl; 
} 

Tout ce qui accumule le fait est réglé « somme » au troisième paramètre, puis pour toutes les valeurs de la val 'du premier paramètre à second paramètre, faire:

sum = sum + val 

puis retourne 'sum'. En dépit du fait que Accumuler est déclarée en <numeric> il fonctionnera pour tout ce qui met en œuvre operator+()

+0

Merci, j'ai essayé d'utiliser accumuler avec le 3ème paramètre comme ago, ne fonctionne pas, j'ai aussi essayé avec back_inserter qui a échoué aussi. Pouvez-vous expliquer comment cela fonctionne? Merci beaucoup. – Bogdan

+1

Il prend chaque élément dans le vecteur de .begin() à .end() et les accumule dans le troisième paramètre, qui est une chaîne std :: vide passée en tant que temporaire. La valeur de retour de std :: acumulate() est le résultat de l'accumulation, passé par la valeur. –

+3

Btw, cette approche peut échelonner très mal car il pourrait y avoir un lof de copie/reallicating impliqué. – sellibitze

6

Je ne suis pas sûr de votre question.Où se situe le problème? C'est juste une question de boucle.

#include<vector> 
#include<string> 
#include<iostream> 

int main() 
{ 
    std::string str = "Hello World!"; 
    std::vector<string> vec (10,str); 

    for(size_t i=0;i!=vec.size();++i) 
     str=str+vec[i]; 
    std::cout<<str; 
} 

EDIT:

Utilisez for_each() de <algorithm>

Essayez ceci:

#include<vector> 
#include<string> 
#include<iostream> 
#include<algorithm> 
using namespace std; 
string i; 
void func(string &k) 
{ 
    i+=k; 
} 
int main() { 
    string str = "Hello World!"; 
    vector<string> vec (10,str); 

    for_each(vec.begin(),vec.end(),func); 
    cout<<i; 
    return 0; 
    } 
+1

Je dois utiliser une fonction de l'en-tête de l'algorithme pour le faire. – Bogdan

+0

Ce n'est pas beau, mais je suppose que cela fonctionne, ty – Bogdan

+0

La question en elle-même n'est pas si belle. xD –

12

Que diriez-vous std :: copy?

std::ostringstream os; 
std::copy(vec_strings.begin(), vec_string.end(), ostream_iterator<string>(os)); 
cout << os.str() << endl; 
6

L'extrait suivant compile dans Visual C++ 2012 et utilise une fonction lambda:

int main() { 
    string str = "Hello World!"; 
    vector<string> vec (10,str); 

    stringstream ss; 
    for_each(vec.begin(), vec.end(), [&ss] (const string& s) { cat(ss, s); }); 
    string a = ss.str(); 

    cout << a << endl; 
} 

L'exemple accumulate dans la 1ère réponse est élégante, mais comme sellibitze a souligné, il réaffecte à chaque concaténation et échelles à O (N²). Cet echelle for_each est à environ O (N). J'ai profilé les deux solutions avec des chaînes de 100K; l'exemple accumulate a pris 23,6 secondes, mais cet extrait for_each a pris 0,054 sec.

+1

Il pourrait être encore plus rapide de créer un appel à 'std :: sring' (taille finale)', puis d'utiliser '+ =', ce qui devrait être rapide puisque le tampon est déjà de la bonne taille. –