Ich benutze einfach std::find
, aber ich kann die erste Position nur zurück.
Weil Sie Ihre Suche immer am Anfang des Containers starten.
Aber std::find
kann irgendein Bereich, nicht nur ein kompletter Behälter suchen; Starten Sie stattdessen einfach jede neue Suche , in der die letzte gestoppt wurde. Hier
ist ein Beispiel auf Ihrem vorhandenen Code basiert:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main() {
std::vector<std::string> vec;
vec.push_back("a");
vec.push_back("i");
vec.push_back("g");
vec.push_back("h");
vec.push_back("l");
vec.push_back("a");
vec.push_back("n");
vec.push_back("d");
vec.push_back("e");
vec.push_back("r");
bool found_at_least_once = false;
auto start_it = begin(vec);
while (start_it != end(vec)) {
start_it = std::find(start_it, end(vec), "a");
if (start_it != end(vec)) {
auto const pos = std::distance(begin(vec), start_it);
std::cout << "FOUND AT : " << pos << '\n';
++start_it;
found_at_least_once = true;
}
}
if (!found_at_least_once) {
std::cout << "NOT FOUND" << '\n';
}
}
Beobachtungen über dieses spezifische Programm:
start_it
ist der Iterator, wo jede Suche beginnt. Es ist zunächst begin(vec)
.
- Die Schleife wird fortgesetzt, solange
start_it
nicht bei end(vec)
angekommen ist. Wenn der Vektor leer ist (begin(vec) == end(vec)
), wird die Schleife nie eingegeben.
std::find
liefert einen Iterator das gefundene Element oder end(vec)
. Wenn das Element nicht gefunden wird, wird die Schleife beendet, weil start_it
end(vec)
ist.
- Wenn es gefunden wird, dann startet die nächste Schleifeniteration die
std::find
Suche ein Element hinter dem letzten Ergebnis wegen der ++start_it;
Linie.
- Da Sie schließlich trotzdem bei
end(vec)
ankommen, müssen Sie sich explizit erinnern, ob mindestens eine Suche erfolgreich war, daher die boolesche Variable. Das ist, weil Sie spezielle Behandlung für den Fall wünschen, wenn nichts gefunden wird. Wenn das Ziel stattdessen wäre, einfach nichts zu drucken, wenn "a"
nie gefunden wird, dann brauchen Sie die boolesche Variable nicht.
Allgemeine Codierung Stil Beobachtungen:
auto
ist eine gute Möglichkeit, die Notwendigkeit für Rechtschreibung komplizierte Art Erklärungen zu entfernen, ohne Typsicherheit zu opfern.
- Bevorzugen Sie die Nichtmitgliedsfunktionen
begin
und end
zu den Elementfunktionen.
- Verwenden Sie nicht
using namespace std;
.
- Enthalten Sie
<string>
, wenn Sie std::string
verwenden, oder Ihr Code ist plattformabhängig ohne jeden Grund.
- Verwenden Sie
'\n'
anstelle von std::endl
.
Ich persönlich glaube nicht, eine std::find
/std::distance
-basierte Lösung hier eine sehr gute Idee ist. Aus Gründen der Klarheit des Codes, würde ich wahrscheinlich eine einfache alte for
Schleife wie folgt verwenden:
bool found_at_least_once = false;
for (std::vector<std::string>::size_type pos = 0; pos < vec.size(); ++pos) {
if (vec[pos] == "a") {
std::cout << "FOUND AT : " << pos << '\n';
found_at_least_once = true;
}
}
Beachten Sie, dass vec.size()
kann und soll 17 durch size(vec)
in C++ ersetzt werden.
Mögliches Duplikat von [Ermitteln der Indizes aller Vorkommen eines Elements in einem Vektor] (http://stackoverflow.com/questions/25846235/finding-the-indexes-of-all-occurrrences-of-an-element -in-vector) –
std :: find (it + 1, vec.end(), "a")? – stijn