Saya memiliki vektor vektor T:
std::vector<std::vector<T>> vector_of_vectors_of_T;
Saya ingin menggabungkan semuanya menjadi satu vektor T:
std::vector<T> vector_of_T;
Saat ini saya menggunakan metode ini:
size_t total_size{ 0 };
for (auto const& items: vector_of_vectors_of_T){
total_size += items.size();
}
vector_of_T.reserve(total_size);
for (auto const& items: vector_of_vectors_of_T){
vector_of_T.insert(end(vector_of_T), begin(items), end(items));
}
Apakah ada metode yang lebih sederhana? Seperti fungsi std siap? Jika tidak, apakah ada cara yang lebih efisien untuk melakukannya secara manual?
Ini latihan yang bagus untuk mencoba dan menulis generik join
. Kode di bawah ini mengambil wadah bersarang R1<R2<T>
dan mengembalikan wadah yang digabungkan R1<T>
. Perhatikan bahwa karena parameter pengalokasi di Pustaka Standar, ini agak tidak praktis. Tidak ada upaya yang dilakukan untuk memeriksa kompatibilitas alokator dll.
Untungnya, ada action::join
berfungsi di perpustakaan range-v3 mendatang oleh Eric Niebler, yang sudah cukup kuat dan bekerja hari ini di Clang:
#include <range/v3/all.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
// quick prototype
template<template<class, class...> class R1, template<class, class...> class R2, class T, class... A1, class... A2>
auto join(R1<R2<T, A2...>, A1...> const& outer)
{
R1<T, A2...> joined;
joined.reserve(std::accumulate(outer.begin(), outer.end(), std::size_t{}, [](auto size, auto const& inner) {
return size + inner.size();
}));
for (auto const& inner : outer)
joined.insert(joined.end(), inner.begin(), inner.end());
return joined;
}
int main()
{
std::vector<std::vector<int>> v = { { 1, 2 }, { 3, 4 } };
// quick prototype
std::vector<int> w = join(v);
std::copy(w.begin(), w.end(), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
// Eric Niebler's range-v3
std::vector<int> u = ranges::action::join(v);
std::copy(u.begin(), u.end(), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
}
Contoh Langsung
Menggunakan back_inserter
dan move
;
size_t total_size{ 0 };
for (auto const& items: vector_of_vectors_of_T){
total_size += items.size();
}
vector_of_T.reserve(total_size);
for (auto& items: vector_of_vectors_of_T){
std::move(items.begin(), items.end(), std::back_inserter(vector_of_T));
}
Dari pada copying
, std::move
memberikan peningkatan kinerja sedikit.
Saya kira Anda bisa mencoba std::merge
/std::move
digunakan dalam satu loop - yang sudah ada algoritma std. Tidak tahu apakah itu lebih cepat.