Wie wähle ich eine Teilmenge aus einem stl :: vector oder einer Liste?

8

c ++ - Gurus:

Es gibt einige nützliche C ++ stl-Algorithmen wie Suchen oder Suchen. Es scheint jedoch, dass sie nur einen einzigen Interator zurückgeben.

Was ist, wenn ich einen SQL-Stil für einen STL-Container auswählen möchte? sagen wir, ein Vektor (könnte zur Liste oder Karte erweitert werden). etwas wie

%Vor%

Die Ausgabe sollte ein Bereich sein, etwa ein std :: pair, das dem Rückgabewert der Methoden in boost :: multi-index

ähnelt

Gibt es sowas in stl? oder irgendwelche feste Libraries ähnlich?

    
James Bond 23.11.2013, 22:07
quelle

4 Antworten

5

Sie haben grundsätzlich zwei Ansätze:

1) Was Sie in einem Kommentar oben sagen, schreiben Sie (Iteratoren zeigen auf) die Ergebnisse in einen Container von Iteratoren. Das wird ungefähr so ​​aussehen:

%Vor%

Dann nennst du es wie folgt:

%Vor%

Sie könnten select_iterators in anderen Algorithmen definieren, indem Sie copy_if und boost::counting_iterator verwenden, aber ich denke nicht, dass es sich lohnt, wenn die direkte Implementierung so einfach ist. Es würde aussehen wie:

%Vor%

2) Anstatt alle Werte vorab zu testen und die Ergebnisse irgendwo zu schreiben, definieren Sie einen Iterator, der bei jeder Inkrementierung über den ursprünglichen Bereich hinausgeht, bis er die nächste Übereinstimmung findet. Boost bietet zwei Möglichkeiten, boost::filter_iterator und boost::adaptors::filter . Du könntest also schreiben:

%Vor%

Was auch immer Sie mit Ihren Ergebnissen tun möchten, Sie können von results.begin() nach results.end() iterieren, als wäre es ein Container. Es ist kein Container, es erfüllt nicht die gesamte Containerschnittstelle. Es erfüllt eine von Boost definierte Schnittstelle namens Range, die "über iteriert werden kann". Es ist eigentlich nur eine gefilterte Ansicht von myfoos , also wird kein Foo -Objekt kopiert oder verschoben.

    
Steve Jessop 23.11.2013, 22:59
quelle
3

Wenn Sie Ihren Vektor ändern können std :: partition wäre die Wahl. Hier, wie würdest du es nennen:

%Vor%

Sie befinden sich zwischen v.begin() und p .

    
Johan 23.11.2013 22:15
quelle
2

Sie könnten nach boost::range

A boost::range ist effektiv ein Paar von Iteratoren, die einen Bereich von Elementen eines Containers begrenzen. Die Bibliothek enthält verschiedene Algorithmen, die einen Bereich aus einem Bereich zurückgeben (z. B. den Bereich äquivalenter Werte im Container mit einem vom Benutzer bereitgestellten Äquivalenzfunktor).

    
rici 23.11.2013 22:11
quelle
1
%Vor%

Dinge zu beachten:

1.) Sie haben angegeben, dass Ihr Container von iterator und nicht von const_iterator sein soll. Der Typ entspricht dem Anfangs- und Endbereich, den Sie an die Funktion übergeben. Der Typ ist beispielsweise const_iterator für const containers, er wird auch const_iterator sein, wenn Sie vector::cbegin und vector::cend verwenden, und er wird nicht kompiliert, wenn Sie andere Iteratoren wie vector::begin verwenden. und vector::cend .

2.) Vektoren verlieren oft ihre Iterator-Gültigkeit, also seien Sie vorsichtig bei der Verwendung dieser Iteratoren. Wenn Sie beispielsweise zum Vektor hinzufügen, könnte jeder von dieser Funktion zurückgegebene Iterator ungültig sein. Um dies zu verhindern, verwenden Sie entweder einen anderen Container (z. B. Liste) oder verwenden Sie vector::reserve .

3.) Der Vorwärts-Iterator muss etwas sein, das ++ unterstützt, und wenn dereferenziert wird, hat es denselben Typ wie InputIterator (z. B. vector<int>::iterator ). Es muss auch ein gültiger Iterator bleiben, nachdem es inkrementiert wurde, oder die Funktion wäre bedeutungslos. Der Ausgabe-Iterator muss an einen Platz mit genügend Platz für alle gefundenen Iteratoren gehen, um pred zu setzen. Wenn Sie den Speicherplatz nicht im Voraus kennen, können Sie std::back_inserter von <iterator> mit einem Container verwenden, für den container::push_back definiert ist, und dieser wird nach Bedarf erweitert.

Hier ist ein Test der Funktion für Sie zu verstehen, wie es funktioniert.

%Vor%     
user904963 23.11.2013 23:01
quelle

Tags und Links