2017-03-18 3 views
0

Ich verwende den folgenden Code, um eine Zeichenfolge in std::vector von std::string zu finden. Aber wie kann man alle Positionen eines bestimmten Elements zurückgeben?Wie findet man alle Positionen eines Elements mit std :: find?

Ich verwende einfach std::find, aber ich kann nur die erste Position zurückgeben.

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

using namespace std; 

int main() { 
    vector<string> vec; 
    vector<string>::iterator it; 

    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"); 

    it=find(vec.begin(),vec.end(),"a"); 
    int pos = distance(vec.begin(), it); 

    if(it!=vec.end()){ 
     cout<<"FOUND AT : "<<pos<<endl; 
    } 
    else{ 
     cout<<"NOT FOUND"<<endl; 
    } 
    return 0; 
} 

Ich konnte nur 0 bekommen, wie kann ich 5 auch bekommen?

+5

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) –

+2

std :: find (it + 1, vec.end(), "a")? – stijn

Antwort

-2

dieser Code funktioniert für mich:

Edit: leider nicht sorgfältig die Frage gelesen. ;)

Edit: danke für das feedback, das ist warning-entfernt mein code!

auto begin = vec.begin(); 
unsigned int pos = 0; 
while (true) 
{ 
    auto result = find(begin, vec.end(), "a"); 
    if (result == vec.end())  break; 
    else 
    { 
    if(result == begin) printf("pos: %d\n", pos); 
    ++begin; 
    ++pos; 
    } 
} 
+0

Sie müssen Ihren Code erklären, nicht nur kopieren und einfügen! –

+0

Dies beantwortet die gestellte Frage nicht. OP möchte Positionen von ** beiden ** '" a "' Elementen erhalten, Ihr Code kann nur einen erkennen. –

+0

Sie haben Recht, dann wird mein Code ändern. – sailfish009

2

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_itend(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.

+0

wollte zu Ihrer ersten Version kommentieren, dass das do {} while() etwas seltsam aussieht und nicht benötigt wird, aber Sie haben es bereits behoben:] – stijn

Verwandte Themen