1016 Stimmen

Verkettung von zwei std::Vektoren

Wie verkette ich zwei std::vector s?

10 Stimmen

Die gegebenen Antworten sind nicht wirklich zusammenhängend. Sie fügen eine Kopie an. Es könnte (aus Gründen der Effizienz) sinnvoll sein, eine std::vector concatenate-Methode zu erstellen, allerdings würde dies eine ausgeklügelte gemeinsame Nutzung der Verwaltung der Knoten erfordern, und das ist wahrscheinlich der Grund, warum dies noch nicht geschehen ist.

16 Stimmen

@FauChristian: Nein, unter Effizienzgesichtspunkten kann es keinen Nutzen geben. Der Vektorspeicher muss kontinuierlich sein, also ist das, was Sie vorschlagen, unmöglich. Wenn Sie "eine ausgeklügelte gemeinsame Nutzung der Verwaltung der Knoten" wollten und die Vektorklasse auf diese Weise ändern würden, würden Sie bei einer Deque landen. Selbst dann ist es sehr schwierig, den Speicher in der vorgeschlagenen Weise wiederzuverwenden, auch wenn es allmählich ein wenig praktikabler wäre. Ich glaube nicht, dass es derzeit implementiert ist. Die Hauptsache ist, dass in einem solchen Sharing von Management-Knoten (eine deque) der Endknoten teilweise leer sein könnte.

18 Stimmen

Bin ich der Einzige, der sich fragt, warum dies nicht als a + b o a.concat(b) in der Standardbibliothek? Vielleicht wäre die Standardimplementierung suboptimal, aber nicht jede Array-Verkettung muss mikro-optimiert sein

1voto

Aleph0 Punkte 5428

Diese Lösung mag etwas kompliziert sein, aber boost-range hat auch einige andere schöne Dinge zu bieten.

#include <iostream>
#include <vector>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    boost::copy(b, std::back_inserter(a));
    for (auto& iter : a) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

Oft ist es die Absicht, die Vektor a y b einfach eine Operation darüber laufen lassen. In diesem Fall gibt es die lächerlich einfache join Funktion.

#include <iostream>
#include <vector>
#include <boost/range/join.hpp>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    std::vector<int> c = { 7,8,9 };
    // Just creates an iterator
    for (auto& iter : boost::join(a, boost::join(b, c))) {
        std::cout << iter << " ";
    }
    std::cout << "\n";
    // Can also be used to create a copy
    std::vector<int> d;
    boost::copy(boost::join(a, boost::join(b, c)), std::back_inserter(d));
    for (auto& iter : d) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

Bei großen Vektoren kann dies ein Vorteil sein, da kein Kopieren stattfindet. Es kann auch zum Kopieren verwendet werden und lässt sich leicht auf mehr als einen Container verallgemeinern.

Aus irgendeinem Grund gibt es nichts wie boost::join(a,b,c) was vernünftig sein könnte.

0voto

Jonathan Mee Punkte 36373

Wenn Sie nach einer Möglichkeit suchen, einen Vektor nach der Erstellung an einen anderen anzuhängen, vector::insert ist die beste Lösung, wie zum Beispiel schon mehrfach geantwortet wurde:

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

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

Leider gibt es keine Möglichkeit, eine const vector<int> müssen Sie, wie oben beschrieben, konstruieren und dann insert .


Wenn Sie tatsächlich nach einem Container suchen, der die Verkettung dieser beiden vector<int> s, kann es etwas Besseres für Sie geben, wenn:

  1. Ihr vector enthält Primitive
  2. Die enthaltenen Primitive haben eine Größe von 32 Bit oder weniger
  3. Sie wollen eine const Container

Wenn alle oben genannten Punkte zutreffen, würde ich vorschlagen, die basic_string der char_type entspricht der Größe des Primitivs, das in Ihrer vector . Sie sollten eine static_assert in Ihrem Code, um sicherzustellen, dass diese Größen konsistent bleiben:

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

Wenn dies der Fall ist, können Sie einfach tun:

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

Für weitere Informationen über die Unterschiede zwischen string y vector können Sie hier nachsehen: https://stackoverflow.com/a/35558008/2642059

Ein Live-Beispiel für diesen Code finden Sie hier: http://ideone.com/7Iww3I

0voto

rekkalmd Punkte 143

Sie können dies mit vorimplementierten STL-Algorithmen tun, indem Sie eine Vorlage für einen polymorphen Typ verwenden.

#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>

void concat(std::vector<T>& valuesa, std::vector<T>& valuesb){

     for_each(valuesb.begin(), valuesb.end(), [&](int value){ valuesa.push_back(value);});
}

int main()
{
    std::vector<int> values_p={1,2,3,4,5};
    std::vector<int> values_s={6,7};

   concat(values_p, values_s);

    for(auto& it : values_p){

        std::cout<<it<<std::endl;
    }

    return 0;
}

Sie können den zweiten Vektor löschen, wenn Sie ihn nicht weiter verwenden wollen ( clear() Methode).

-2voto

GobeRadJem32 Punkte 102

Verketten Sie zwei std::vector-s con for Schleife in einer std::vector .

    std::vector <int> v1 {1, 2, 3}; //declare vector1
    std::vector <int> v2 {4, 5}; //declare vector2
    std::vector <int> suma; //declare vector suma

    for(int i = 0; i < v1.size(); i++) //for loop 1
    {
         suma.push_back(v1[i]);
    }

    for(int i = 0; i< v2.size(); i++) //for loop 2
    {
         suma.push_back(v2[i]);
    }

    for(int i = 0; i < suma.size(); i++) //for loop 3-output
    {
         std::cout << suma[i];
    }

1 Stimmen

Abgesehen davon, dass es nicht funktioniert, ist dieser Code sehr unidiomatisch. Sie sollten zumindest Folgendes verwenden auto Iteratoren anstelle der manuellen Indizierung. Es ist nicht wichtig, welchen Index Sie verketten, sondern nur, dass die Verkettung sequentiell erfolgt.

0 Stimmen

@TarickWelling Ich verstehe nicht, warum Sie sagen, dass dieser Code nicht funktioniert, könnten Sie genauer sein?

7 Stimmen

Haben Sie das Datum meines Kommentars überprüft? Sie behoben die Fehler in Ihrem Code jetzt ist es einfach nicht idiomatisch.

-5voto

nvnhcmus Punkte 1

Um ehrlich zu sein, könnten Sie zwei Vektoren schnell verketten, indem Sie Elemente aus zwei Vektoren in den anderen kopieren oder nur einen der beiden Vektoren anhängen! Das hängt von deinem Ziel ab.

Methode 1: Weisen Sie dem neuen Vektor eine Größe zu, die der Summe der Größe der beiden ursprünglichen Vektoren entspricht.

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

Methode 2: Anhängen von Vektor A durch Hinzufügen/Einfügen von Elementen des Vektors 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());

4 Stimmen

Was fügt Ihre Antwort hinzu, das nicht bereits in anderen Antworten enthalten ist?

18 Stimmen

@Mat: Fettgedruckte Zeichen.

0 Stimmen

Wenn die ursprünglichen Vektoren danach nicht mehr benötigt werden, kann es besser sein, die std::move_iterator so dass Elemente verschoben und nicht kopiert werden. (siehe de.cppreference.com/w/cpp/iterator/move_iterator ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X