2009-12-31 26 views
20

Tôi đã đọc Accelerated C++ và tôi phải nói đó là một cuốn sách thú vị.Kết hợp vectơ dây

Trong chương 6, tôi phải sử dụng hàm từ < thuật toán > để nối từ một vector < chuỗi > thành một chuỗi đơn. Tôi có thể sử dụng tích lũy, nhưng nó không giúp đỡ bởi vì chuỗi container chỉ có thể push_back ký tự.

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

    return 0; 
} 

Làm cách nào để tham gia chuỗi?

+0

Bạn đang hỏi gì? – tster

Trả lời

48

Giả sử đây là câu hỏi 6.8, nó không nói rằng bạn phải sử dụng tích lũy - nó nói sử dụng "thuật toán thư viện". Tuy nhiên, bạn có thể sử dụng tích lũy:

#include <numeric> 

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

Tất cả những gì tích lũy không được thiết lập 'tổng hợp' với tham số thứ ba, và sau đó cho tất cả các giá trị 'val' từ tham số đầu tiên tham số thứ hai, làm:

sum = sum + val 

rồi trả về 'tổng'. Mặc dù thực tế rằng tích lũy được khai báo trong <numeric> nó sẽ hoạt động cho bất cứ điều gì thực hiện operator+()

+0

Cảm ơn, tôi đã thử sử dụng tích lũy với tham số thứ 3 là a.begin, không hoạt động, tôi cũng đã thử với back_inserter không thành công. Bạn có thể giải thích cách hoạt động của nó không? Cảm ơn rất nhiều. – Bogdan

+1

Mỗi phần tử trong vector từ .begin() đến .end() và tích lũy chúng vào tham số thứ ba, là một chuỗi trống std :: được truyền vào như một tạm thời. std :: acumulate() 's giá trị trả về là kết quả của sự tích lũy, thông qua giá trị. –

+3

Btw, cách tiếp cận này có thể quy mô rất nặng vì có thể có rất nhiều việc sao chép/thực hiện liên quan. – sellibitze

6

Tôi không chắc chắn về câu hỏi của bạn. Có vấn đề gì? Nó chỉ là vấn đề của một vòng lặp.

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

Sử dụng for_each() từ <algorithm>

Hãy thử điều này:

#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

Tôi phải sử dụng hàm từ tiêu đề thuật toán để thực hiện việc này. – Bogdan

+0

Nó không đẹp, nhưng tôi đoán nó hoạt động, ty – Bogdan

+0

Câu hỏi chính nó không phải là tốt đẹp. xD –

12

Làm thế nào về std :: copy?

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

Đoạn sau biên dịch trong Visual C++ 2012 và sử dụng một hàm 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; 
} 

Các accumulate dụ trong câu trả lời 1 là tao nhã, nhưng như sellibitze chỉ ra, nó reallocates với nhau nối và tỷ lệ tại O (N²). Đoạn mã này for_each ở khoảng O (N). Tôi đã lược tả cả hai giải pháp với chuỗi 100K; ví dụ accumulate mất 23,6 giây, nhưng đoạn mã for_each mất 0,054 giây này.

+1

Thậm chí còn có thể tạo một lệnh 'std :: sring'' dự trữ (kích thước cuối cùng) ', sau đó chỉ cần sử dụng' + = 'nhanh hơn vì bộ đệm đã có kích thước phù hợp. –

Các vấn đề liên quan