408 Stimmen

Wie extrahiert man am besten einen Untervektor aus einem Vektor?

Angenommen, ich habe eine std::vector (nennen wir es myVec ) der Größe N . Wie kann man am einfachsten einen neuen Vektor konstruieren, der aus einer Kopie der Elemente X bis Y besteht, wobei 0 <= X <= Y <= N-1? Zum Beispiel, myVec [100000] über myVec [100999] in einem Vektor der Größe 150000 .

Wenn dies nicht effizient mit einem Vektor getan werden kann, gibt es einen anderen STL-Datentyp, die ich stattdessen verwenden sollte?

490voto

Greg Rogers Punkte 34400
vector<T>::const_iterator first = myVec.begin() + 100000;
vector<T>::const_iterator last = myVec.begin() + 101000;
vector<T> newVec(first, last);

Es ist eine O(N)-Operation, den neuen Vektor zu konstruieren, aber es gibt keinen besseren Weg.

113voto

Martin York Punkte 245363

Verwenden Sie einfach den Vektorkonstruktor.

std::vector<int>   data();
// Load Z elements into data so that Z > Y > X

std::vector<int>   sub(&data[100000],&data[101000]);

68voto

Dávid Tóth Punkte 1823

Diese Diskussion ist schon ziemlich alt, aber die einfachste Lösung wurde noch nicht erwähnt, nämlich Listeninitialisierung :

 vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2}; 

Es erfordert c++11 oder höher.

Beispiel für die Verwendung:

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

using namespace std;

int main(){

    vector<int> big_vector = {5,12,4,6,7,8,9,9,31,1,1,5,76,78,8};
    vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2};

    cout << "Big vector: ";
    for_each(big_vector.begin(), big_vector.end(),[](int number){cout << number << ";";});
    cout << endl << "Subvector: ";
    for_each(subvector.begin(), subvector.end(),[](int number){cout << number << ";";});
    cout << endl;
}

Ergebnis:

Big vector: 5;12;4;6;7;8;9;9;31;1;1;5;76;78;8;
Subvector: 6;7;8;9;9;31;1;1;5;76;

36voto

einpoklum Punkte 100527

Heutzutage verwenden wir span s! Sie würden also schreiben:

#include <gsl/span>

...
auto start_pos = 100000;
auto length = 1000;
auto span_of_myvec = gsl::make_span(myvec);
auto my_subspan = span_of_myvec.subspan(start_pos, length);

um eine Spanne von 1000 Elementen des gleichen Typs zu erhalten wie myvec 's. Oder eine etwas knappere Form:

auto my_subspan = gsl::make_span(myvec).subspan(1000000, 1000);

(aber ich mag das nicht so sehr, da die Bedeutung der einzelnen numerischen Argumente nicht ganz klar ist; und es wird noch schlimmer, wenn die Länge und start_pos von der gleichen Größenordnung sind).

Wie auch immer, denken Sie daran, dass es sich um keine Kopie, sondern nur eine Ansicht der Daten im Vektor, seien Sie also vorsichtig. Wenn Sie eine tatsächliche Kopie wollen, können Sie das tun:

std::vector<T> new_vec(my_subspan.cbegin(), my_subspan.cend());

Anmerkungen:

32voto

Anteru Punkte 18671

std::vector<T>(input_iterator, input_iterator) in Ihrem Fall foo = std::vector<T>(myVec.begin () + 100000, myVec.begin () + 150000); siehe zum Beispiel aquí

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