Apakah ada kelas C ++ Standard Template Library yang menyediakan serangkaian fungsi Rangkaian efisien, mirip dengan C # 's StringBuilder atau Jawa StringBuffer ?
c++
stl
string-concatenation
An̲̳̳drew
sumber
sumber
std::ostringstream
.Jawaban:
Perhatikan jawaban ini baru-baru ini mendapat perhatian. Saya tidak menganjurkan ini sebagai solusi (ini adalah solusi yang saya lihat di masa lalu, sebelum STL). Ini adalah pendekatan yang menarik dan hanya boleh diterapkan di atas
std::string
ataustd::stringstream
jika setelah membuat profil kode Anda Anda menemukan ini membuat perbaikan.Saya biasanya menggunakan salah satu
std::string
ataustd::stringstream
. Saya tidak pernah punya masalah dengan ini. Saya biasanya akan memesan kamar terlebih dahulu jika saya tahu ukuran kasar tali sebelumnya.Saya telah melihat orang lain membuat pembuat string yang dioptimalkan sendiri di masa lalu.
Ini menggunakan dua string satu untuk sebagian besar string dan yang lainnya sebagai area awal untuk merangkai string pendek. Ini mengoptimalkan penambahan dengan cara batching operasi penambahan pendek dalam satu string kecil kemudian menambahkan ini ke string utama, sehingga mengurangi jumlah realokasi yang diperlukan pada string utama saat menjadi lebih besar.
Saya belum meminta trik ini dengan
std::string
ataustd::stringstream
. Saya pikir itu digunakan dengan perpustakaan string pihak ketiga sebelum std :: string, itu sudah lama sekali. Jika Anda mengadopsi strategi seperti profil ini, aplikasi Anda terlebih dahulu.sumber
scratch
string benar-benar menyelesaikan apa pun di sini. Jumlah realokasi string utama sebagian besar akan menjadi fungsi dari ukuran finalnya, bukan jumlah operasi tambahan, kecualistring
implementasinya benar-benar buruk (yaitu, tidak menggunakan pertumbuhan eksponensial). Jadi, "menumpuk"append
tidak akan membantu karena begitu dasarnyastring
itu besar itu hanya akan tumbuh sesekali. Selain itu, ia menambahkan banyak operasi penyalinan yang redundan, dan mungkin lebih banyak realokasi (karena itu panggilan kenew
/delete
) karena Anda menambahkan string pendek.str.reserve(1024);
akan lebih cepat dari hal iniCara C ++ adalah dengan menggunakan std :: stringstream atau hanya gabungan string sederhana. String C ++ bisa berubah sehingga pertimbangan kinerja gabungan tidak terlalu menjadi perhatian.
berkenaan dengan pemformatan, Anda dapat melakukan semua pemformatan yang sama pada aliran, tetapi dengan cara yang berbeda, mirip dengan
cout
. atau Anda dapat menggunakan functor yang sangat diketik yang merangkum ini dan menyediakan antarmuka seperti String.Format misalnya boost :: formatsumber
StringBuilder
ada adalah untuk menutupi ketidakefisienan tipe String dasar Java yang tidak berubah . Dengan kata lainStringBuilder
adalah tambal sulam, jadi kita harus senang kita tidak perlu kelas seperti itu di C ++.O(n)
pada umumnya.The
std::string.append
fungsi bukan pilihan yang baik karena tidak menerima berbagai bentuk data. Alternatif yang lebih bermanfaat adalah menggunakanstd::stringstream
; seperti itu:sumber
std::string
adalah setara C ++: Ini bisa berubah.sumber
Anda dapat menggunakan .append () untuk string yang digabungkan.
Saya pikir Anda bahkan dapat melakukannya:
Adapun operasi pemformatan C #
StringBuilder
, saya percayasnprintf
(atausprintf
jika Anda ingin mengambil risiko menulis kode kereta ;-)) ke dalam array karakter dan mengkonversi kembali ke string adalah tentang satu-satunya pilihan.sumber
Karena
std::string
dalam C ++ bisa berubah, Anda dapat menggunakannya. Ini memiliki+= operator
danappend
fungsi.Jika Anda perlu menambahkan data numerik gunakan
std::to_string
fungsi.Jika Anda menginginkan fleksibilitas yang lebih besar dalam bentuk mampu membuat serialisasi objek apa pun menjadi string, gunakan
std::stringstream
kelas. Tetapi Anda harus mengimplementasikan fungsi operator streaming Anda sendiri agar dapat bekerja dengan kelas kustom Anda sendiri.sumber
std :: string's + = tidak berfungsi dengan const char * (apa yang tampak seperti "string untuk ditambahkan" tampaknya), jadi pasti menggunakan stringstream adalah yang paling dekat dengan apa yang diperlukan - Anda hanya menggunakan << bukannya +
sumber
Pembuat string yang nyaman untuk c ++
Seperti banyak orang yang menjawab sebelumnya, std :: stringstream adalah metode pilihan. Ini berfungsi baik dan memiliki banyak opsi konversi dan pemformatan. IMO memiliki satu kelemahan yang cukup merepotkan: Anda tidak dapat menggunakannya sebagai satu liner atau sebagai ekspresi. Anda selalu harus menulis:
yang cukup menjengkelkan, terutama ketika Anda ingin menginisialisasi string dalam konstruktor.
Alasannya adalah, bahwa a) std :: stringstream tidak memiliki operator konversi ke std :: string dan b) operator dari stringstream tidak mengembalikan referensi stringstream, tetapi sebaliknya std :: ostream reference - yang tidak dapat dihitung lebih lanjut sebagai aliran string.
Solusinya adalah mengesampingkan std :: stringstream dan memberikannya operator pencocokan yang lebih baik:
Dengan ini, Anda dapat menulis hal-hal seperti
bahkan di konstruktor.
Saya harus mengakui bahwa saya tidak mengukur kinerja, karena saya belum menggunakannya di lingkungan yang banyak menggunakan pembuatan string, tapi saya berasumsi itu tidak akan jauh lebih buruk daripada std :: stringstream, karena semuanya sudah selesai melalui referensi (kecuali konversi ke string, tapi itu operasi salinan di std :: stringstream juga)
sumber
std::stringstream
tidak berperilaku seperti ini.The Rope wadah mungkin layak jika harus memasukkan / menghapus string ke tempat acak string tujuan atau untuk urutan arang panjang. Berikut adalah contoh dari implementasi SGI:
sumber
Saya ingin menambahkan sesuatu yang baru karena hal berikut:
Pada usaha pertama saya gagal mengalahkan
std::ostringstream
inioperator<<
efisiensi, tetapi dengan lebih banyak upaya saya bisa membuat StringBuilder yang lebih cepat dalam beberapa kasus.
Setiap kali saya menambahkan string, saya hanya menyimpan referensi di suatu tempat dan menambah penghitung ukuran total.
Cara nyata saya akhirnya mengimplementasikannya (Horor!) Adalah dengan menggunakan buffer buram (std :: vector <char>):
untuk byte []
untuk string yang dipindahkan (string ditambahkan dengan
std::move
)std::string
objek (kami memiliki kepemilikan)untuk string
std::string
objek (tidak ada kepemilikan)Ada juga satu optimasi kecil, jika string yang dimasukkan terakhir dipindahkan, itu memeriksa byte gratis tetapi tidak terpakai dan menyimpan byte lebih lanjut di sana daripada menggunakan buffer buram (ini adalah untuk menghemat beberapa memori, itu sebenarnya membuatnya sedikit lebih lambat , mungkin juga bergantung pada CPU, dan jarang melihat string dengan ruang ekstra tetap)
Ini akhirnya sedikit lebih cepat daripada
std::ostringstream
tetapi memiliki beberapa kelemahan:ostringstream
kesimpulan? menggunakan
std::ostringstream
Ini sudah memperbaiki bottleneck terbesar sementara kecepatan beberapa% poin dengan implementasi tambang tidak sebanding dengan kerugiannya.
sumber