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

45voto

James Curran Punkte 98228
std::vector<int> first;
std::vector<int> second;

first.insert(first.end(), second.begin(), second.end());

38voto

Jarod42 Punkte 189146

Mit Bereich v3 haben Sie möglicherweise eine faule Verkettung:

ranges::view::concat(v1, v2)

Demo .

14 Stimmen

Ich gehe davon aus, dass dies die angemessene Antwort im Jahr 2023 oder so sein wird.

37voto

ST3 Punkte 8392

Ich bevorzuge eine, die bereits erwähnt wurde:

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

Aber wenn Sie C++11 verwenden, gibt es einen allgemeineren Weg:

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

Auch wenn es nicht Teil einer Frage ist, aber es ist ratsam, die reserve vor dem Anhängen, um die Leistung zu verbessern. Und wenn Sie einen Vektor mit sich selbst verketten, ohne ihn zu reservieren, schlägt das fehl, also sollten Sie immer reserve .


Was Sie also im Grunde brauchen:

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());
}

2 Stimmen

std:: wird abgeleitet durch argumentabhängiges Nachschlagen . end(a) ausreichen wird.

5 Stimmen

@Asu ADL wird nur hinzufügen std:: wenn der Typ von a kommt von std was den generischen Aspekt zunichte macht.

0 Stimmen

Guter Punkt. in diesem Fall ist es ein Vektor, so dass es auf jeden Fall funktionieren würde, aber ja, das ist eine bessere Lösung.

23voto

Vikramjit Roy Punkte 436

A allgemeine Leistungssteigerung für concatenate ist es, die Größe der Vektoren zu überprüfen. Und den kleineren mit dem größeren zusammenführen/einfügen.

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

0 Stimmen

So einfach, und doch habe ich nie so darüber nachgedacht!

2 Stimmen

Der Beispielcode ist falsch. v1.insert(v2.end()... ist die Verwendung eines Iterators in v2 zur Angabe der Position in v1 .

1 Stimmen

Sie können auch einen schnellen Tausch vornehmen. @DavidStone Ich habe es so bearbeitet, dass die Reihenfolge der Verknüpfung geändert werden kann. Ist es möglich, am Anfang eines Vektors hinzuzufügen?

17voto

Pavan Chandaka Punkte 9990

Es gibt einen Algorithmus std::merge de C++17 die sehr einfach zu verwenden ist, wenn die Eingangsvektoren sortiert sind,

Nachstehend finden Sie ein Beispiel:

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

int main()
{
    //DATA
    std::vector<int> v1{2,4,6,8};
    std::vector<int> v2{12,14,16,18};

    //MERGE
    std::vector<int> dst;
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));

    //PRINT
    for(auto item:dst)
        std::cout<<item<<" ";

    return 0;
}

15 Stimmen

Ich glaube nicht, dass es einfacher zu benutzen ist als std::vector::insert aber es geht um etwas anderes: das Zusammenführen von zwei Bereichen zu einem neuen Bereich gegenüber dem Einfügen eines Vektors am Ende eines anderen. Ist das in der Antwort erwähnenswert?

0 Stimmen

Ok. Ich habe verstanden, was in der Antwort erwartet wird. Ich werde hinzufügen.

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