Wie erhalte ich die Position eines bestimmten Elements im Zeichenfolgenvektor, um es als Index im Ints-Vektor zu verwenden?

99

Ich versuche, den Index eines Elements in einem Vektor von zu erhalten strings , um ihn als Index in einem anderen Vektor vom intTyp zu verwenden. Ist dies möglich?

Beispiel:

vector <string> Names;
vector <int> Numbers;

 ... 
// condition to check whether the name exists or not
if((find(Names.begin(), Names.end(), old_name_)) != Names.end())  
    {   // if yes
        cout <<"Enter the new name."<< endl;
        cin >> name;
        replace(Names.begin(), Names.end(), old_name_, name);
    }

Jetzt möchte ich die Position von old_nameim NamesVektor erhalten, um damit auf bestimmte Elemente im NumbersVektor zuzugreifen . Damit ich sagen kann:

Numbers[position] = 3 ; // or whatever value assigned here.

Ich habe versucht:

vector <string> :: const_iterator pos;
pos = (find(Names.begin(), Names.end(), old_name_))
Numbers[pos] = 3;

aber offensichtlich funktioniert das nicht, da poses vom Typ string ist!

Nour
quelle
Ich denke, dies sollte stackoverflow.com/questions/1425349/…
Francesco Vollero
Sie sollten std :: map oder std :: unordered_map auschecken.
Etherealone

Antworten:

158

Um eine Position eines Elements in einem Vektor zu erhalten, der einen Iterator kennt, der auf das Element zeigt, subtrahieren Sie einfach v.begin()vom Iterator:

ptrdiff_t pos = find(Names.begin(), Names.end(), old_name_) - Names.begin();

Jetzt müssen Sie prüfen , posgegen Names.size()sehen , ob es außerhalb der Grenzen ist oder nicht:

if(pos >= Names.size()) {
    //old_name_ not found
}

Vektoriteratoren verhalten sich ähnlich wie Array-Zeiger. Das meiste, was Sie über Zeigerarithmetik wissen, kann auch auf Vektoriteratoren angewendet werden.

Ab C ++ 11 können Sie std::distanceanstelle der Subtraktion sowohl Iteratoren als auch Zeiger verwenden:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));
dasblinkenlight
quelle
Entschuldigung, ich kann die Kommentare von @Bob__ nicht sehen, möglicherweise gelöscht? Ich frage mich, warum ptrdiff_tes besser ist als size_tseitdem ptrdiff_t , eine Warnung vor einem Vergleich zwischen vorzeichenbehafteter und vorzeichenloser Ganzzahl
auszulösen
3
@ Hiraku Er hat seinen Kommentar gelöscht. Er schlug die Verwendung vor, ptrdiff_tda Sie damit den Abstand zwischen zwei Iteratorpaaren im selben Container speichern können, selbst in Situationen, in denen das Ergebnis negativ ist. Wenn wir verwenden size_t, müssen wir darauf achten, einen größeren Iterator nicht von einem kleineren Iterator zu subtrahieren.
Dasblinkenlight
Um genauer zu sein, sollten Sie "#include <algorithm>" hinzufügen (für die Verwendung von std :: find). Der Autor der Frage hat dieses "Include" ebenfalls weggelassen.
Grag2015
92

Wenn Sie einen Index möchten, können Sie ihn std::findin Kombination mit verwenden std::distance.

auto it = std::find(Names.begin(), Names.end(), old_name_);
if (it == Names.end())
{
  // name not in vector
} else
{
  auto index = std::distance(Names.begin(), it);
}
Juanchopanza
quelle
8
Warum nicht Const-Iteratoren verwenden?
Dani
-1

Ich bin ein Anfänger, daher hier eine Antwort für Anfänger. Das if in der for-Schleife gibt i an, das dann jedoch nach Bedarf verwendet werden kann, z. B. Numbers [i] in einem anderen Vektor. Das meiste ist zum Beispiel Flusen, das für / wenn wirklich alles sagt.

int main(){
vector<string>names{"Sara", "Harold", "Frank", "Taylor", "Sasha", "Seymore"};
string req_name;
cout<<"Enter search name: "<<'\n';
cin>>req_name;
    for(int i=0; i<=names.size()-1; ++i) {
        if(names[i]==req_name){
            cout<<"The index number for "<<req_name<<" is "<<i<<'\n';
            return 0;
        }
        else if(names[i]!=req_name && i==names.size()-1) {
            cout<<"That name is not an element in this vector"<<'\n';
        } else {
            continue;
        }
    }
Javer
quelle