2009-12-31 14 views
20

He estado leyendo Accelerated C++ y tengo que decir que es un libro interesante.Combinando un vector de cadenas

En el capítulo 6, que tienen que utilizar una función de <algoritmo> para concatenar una cadena de vectores < > en una sola cadena. Podría usar accumulate, pero no ayuda porque los contenedores de cadena solo pueden push_back.

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

    return 0; 
} 

¿Cómo unir las cadenas?

+0

¿Qué estás preguntando? – tster

Respuesta

48

Asumiendo que esto es cuestión 6.8, que no dice que usted tiene que usar acumular - dice usar "un algoritmo de biblioteca". Sin embargo, puede utilizar acumulan:

#include <numeric> 

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

Todo lo que se acumulan hace es establecer 'suma' para el tercer parámetro, y luego para todos los valores 'val' del primer parámetro de segundo parámetro, hacer:

sum = sum + val 

devuelve 'suma'. A pesar de que el acumulo se declara en <numeric> funcionará para cualquier cosa que implemente operator+()

+0

Gracias, traté de usar accumulate con el 3er parámetro como un comienzo, no funcionó, también probé con back_inserter que también falló. ¿Puedes explicar cómo funciona esto? Muchas gracias. – Bogdan

+1

Toma cada elemento en el vector de .begin() a .end() y los acumula en el tercer parámetro, que es un std :: string vacío pasado como temporal. El valor de retorno de std :: acumulate() es el resultado de la acumulación, pasado por valor. –

+3

Por cierto, este enfoque posiblemente se escala muy mal ya que puede haber un lof de copia/reallicación involucrado. – sellibitze

6

No estoy seguro de su pregunta. ¿Dónde radica el problema? Es solo cuestión de un bucle.

#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:

Uso for_each() de <algorithm>

Prueba esto:

#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

Tengo que usar una función del encabezado del algoritmo para hacer esto. – Bogdan

+0

No es agradable, pero supongo que funciona, ty – Bogdan

+0

La pregunta en sí misma no es tan buena. xD –

12

¿Qué tal std :: copy?

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

El siguiente fragmento de código se compila en Visual C++ 2012 y utiliza una función 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; 
} 

El ejemplo accumulate en la primera respuesta es elegante, pero a medida que sellibitze señaló, se reasigna a cada concatenación y escalas en O (N²). Este fragmento de for_each tiene una escala de aproximadamente O (N). Perfilé ambas soluciones con cadenas de 100K; el ejemplo accumulate tomó 23.6 segundos, pero este fragmento for_each tomó 0.054 segundos.

+1

Podría ser aún más rápido crear una llamada 'std :: sring'' reserve (final-size) ', luego simplemente use' + = ', que debería ser rápido ya que el búfer ya tiene el tamaño correcto. –