Come ottenere la posizione di un determinato elemento nel vettore di stringhe, per usarlo come indice nel vettore ints?


99

Sto cercando di ottenere l'indice di un elemento in un vettore di strings, di usarlo come indice in un altro vettore di inttipo, è possibile?

Esempio:

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

Ora voglio ottenere la posizione di old_namenel Namesvettore, per usarla nell'accesso a determinati elementi nel Numbersvettore. Così posso dire:

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

Ho provato a usare:

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

ma ovviamente questo non funziona poiché posè di tipo stringa!



Dovresti controllare std :: map o std :: unordered_map.
Etherealone

Risposte:


158

Per ottenere una posizione di un elemento in un vettore conoscendo un iteratore che punta all'elemento, è sufficiente sottrarre v.begin()dall'iteratore:

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

Ora è necessario controllare poscontro Names.size()per vedere se è fuori limite o meno:

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

gli iteratori vettoriali si comportano in modi simili ai puntatori di array; la maggior parte di ciò che sai sull'aritmetica dei puntatori può essere applicata anche agli iteratori vettoriali.

A partire da C ++ 11 puoi usare std::distanceal posto della sottrazione sia per gli iteratori che per i puntatori:

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

Non riesco a vedere i commenti di @Bob__, forse cancellati? Mi chiedo perché ptrdiff_tsia meglio che da size_tallora ptrdiff_t solleverebbe un avviso di confronto tra interi con segno e senza segno
Hiraku

3
@Hiraku Ha cancellato il suo commento. Ha suggerito di utilizzare ptrdiff_tperché consente di memorizzare la distanza tra qualsiasi coppia di iteratori nello stesso contenitore, anche in situazioni in cui il risultato è negativo. Se usiamo size_tdobbiamo stare attenti a non sottrarre un iteratore più grande da un iteratore più piccolo.
dasblinkenlight

Per essere più precisi, dovresti aggiungere "#include <algorithm>" (per usare std :: find). L'autore della domanda ha omesso anche questo "include".
Grag2015

92

Se vuoi un indice, puoi usarlo std::findin combinazione con 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);
}

8
perché non utilizzare const-iterator?
dani

-1

Sono un principiante quindi ecco una risposta per principianti. Il if nel ciclo for fornisce i che può essere utilizzato comunque necessario come Numbers [i] in un altro vettore. La maggior parte è fluff per motivi di esempio, il for / if dice davvero tutto.

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;
        }
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.