references - vector operation c++




Concatenazione di due std:: vector (12)

Come concatenare due std::vector s?


Aggiungi questo al tuo file di intestazione:

template <typename T> vector<T> concat(vector<T> &a, vector<T> &b) {
    vector<T> ret = vector<T>();
    copy(a.begin(), a.end(), back_inserter(ret));
    copy(b.begin(), b.end(), back_inserter(ret));
    return ret;
}

e usalo in questo modo:

vector<int> a = vector<int>();
vector<int> b = vector<int>();

a.push_back(1);
a.push_back(2);
b.push_back(62);

vector<int> r = concat(a, b);

r conterrà [1,2,62]


Con C ++ 11, preferirei seguire per aggiungere il vettore b a un:

std::move(b.begin(), b.end(), std::back_inserter(a));

quando a e b non sono sovrapposti e b non verrà più utilizzato.

Questo è std::move from <algorithm> , non il solito std::move from.


Dovresti usare vector::insert

v1.insert(v1.end(), v2.begin(), v2.end());

Ecco una soluzione generica che usa la semantica del movimento C ++ 11:

template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, const std::vector<T>& rhs)
{
    if (lhs.empty()) return rhs;
    if (rhs.empty()) return lhs;
    std::vector<T> result {};
    result.reserve(lhs.size() + rhs.size());
    result.insert(result.cend(), lhs.cbegin(), lhs.cend());
    result.insert(result.cend(), rhs.cbegin(), rhs.cend());
    return result;
}

template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, const std::vector<T>& rhs)
{
    lhs.insert(lhs.cend(), rhs.cbegin(), rhs.cend());
    return std::move(lhs);
}

template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, std::vector<T>&& rhs)
{
    rhs.insert(rhs.cbegin(), lhs.cbegin(), lhs.cend());
    return std::move(rhs);
}

template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, std::vector<T>&& rhs)
{
    if (lhs.empty()) return std::move(rhs);
    lhs.insert(lhs.cend(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
    return std::move(lhs);
}

Nota come questo si differenzia dall'appendersi a un vector .


Per essere onesti, è possibile concatenare rapidamente due vettori copiando elementi da due vettori nell'altro o aggiungendo solo uno dei due vettori !. Dipende dal tuo obiettivo.

Metodo 1: Assegna un nuovo vettore con le sue dimensioni è la somma della dimensione di due vettori originali.

vector<int> concat_vector = vector<int>();
concat_vector.setcapacity(vector_A.size() + vector_B.size());
// Loop for copy elements in two vectors into concat_vector

Metodo 2: aggiungi il vettore A aggiungendo / inserendo elementi del vettore B.

// Loop for insert elements of vector_B into vector_A with insert() 
function: vector_A.insert(vector_A .end(), vector_B.cbegin(), vector_B.cend());

Preferisco uno che è già menzionato:

a.insert(a.end(), b.begin(), b.end());

Ma se usi C ++ 11, c'è un altro modo generico:

a.insert(std::end(a), std::begin(b), std::end(b));

Inoltre, non fa parte di una domanda, ma è consigliabile utilizzare la reserve prima di aggiungerla per ottenere prestazioni migliori. E se si concatenano il vettore con se stesso, senza riserva si fallisce, quindi è sempre necessario reserve .

Quindi in pratica quello di cui hai bisogno:

template <typename T>
void Append(std::vector<T>& a, const std::vector<T>& b)
{
    a.reserve(a.size() + b.size());
    a.insert(a.end(), b.begin(), b.end());
}

Se quello che stai cercando è un modo per aggiungere un vettore ad un altro dopo la creazione, vector::insert è la soluzione migliore, come è stato risposto più volte, ad esempio:

vector<int> first = {13};
const vector<int> second = {42};

first.insert(first.end(), second.cbegin(), second.cend());

Purtroppo non c'è modo di costruire un const vector<int> , come sopra è necessario costruire e quindi insert .

Se quello che stai effettivamente cercando è un contenitore per contenere la concatenazione di questi due vector<int> s, potrebbe esserci qualcosa di meglio a tua disposizione, se:

  1. Il tuo vector contiene i primitivi
  2. I tuoi primitivi contenuti sono di dimensioni 32 bit o più piccoli
  3. Vuoi un contenitore const

Se quanto sopra è tutto vero, suggerirei di usare la basic_string who's char_type corrisponde alla dimensione della primitiva contenuta nel tuo vector . Dovresti includere un static_assert nel codice per convalidare queste dimensioni in modo coerente:

static_assert(sizeof(char32_t) == sizeof(int));

Con questa tenuta vera puoi fare solo:

const u32string concatenation = u32string(first.cbegin(), first.cend()) + u32string(second.cbegin(), second.cend());

Per ulteriori informazioni sulle differenze tra string e vector , puoi guardare qui: https://.com/a/35558008/2642059

Per un esempio dal vivo di questo codice puoi guardare qui: http://ideone.com/7Iww3I


Se sei interessato a una forte garanzia di eccezione (quando il costruttore di copie può lanciare un'eccezione):

template<typename T>
inline void append_copy(std::vector<T>& v1, const std::vector<T>& v2)
{
    const auto orig_v1_size = v1.size();
    v1.reserve(orig_v1_size + v2.size());
    try
    {
        v1.insert(v1.end(), v2.begin(), v2.end());
    }
    catch(...)
    {
        v1.erase(v1.begin() + orig_v1_size, v1.end());
        throw;
    }
}

append_move simile con una forte garanzia non può essere implementato in generale se il costruttore di mosse dell'elemento vettoriale può lanciare (che è improbabile ma ancora).


Un aumento generale delle prestazioni per il concatenato consiste nel controllare la dimensione dei vettori. E unire / inserire quello più piccolo con quello più grande.

//vector<int> v1,v2;
if(v1.size()>v2.size()){
    v1.insert(v1.end(),v2.begin(),v2.end());
}else{
    v1.insert(v2.end(),v1.begin(),v1.end());
}

Vorrei usare la funzione di inserimento , qualcosa del tipo:

vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());

vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));

vector1.insert( vector1.end(), vector2.begin(), vector2.end() );




stdvector