Comment obtenir la position d'un certain élément dans le vecteur de chaînes, pour l'utiliser comme index dans le vecteur ints?

99

J'essaye d'obtenir l'index d'un élément dans un vecteur de strings, de l'utiliser comme index dans un autre vecteur deint type, est-ce possible?

Exemple:

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

Maintenant, je veux obtenir la position de old_namedans le Namesvecteur, l'utiliser pour accéder à certains éléments du Numbersvecteur. Pour que je puisse dire:

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

J'ai essayé d'utiliser:

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

mais évidemment cela ne fonctionne pas car il posest de type string!

Nour
la source
Je suppose que cela devrait stackoverflow.com/questions/1425349/...
Francesco Vollero
Vous devriez vérifier std :: map ou std :: unordered_map.
Etherealone

Réponses:

158

Pour obtenir une position d'un élément dans un vecteur connaissant un itérateur pointant vers l'élément, il suffit de soustraire v.begin()à l'itérateur:

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

Maintenant , vous devez vérifier poscontre Names.size()pour voir si elle est en dehors des limites ou non:

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

Les itérateurs vectoriels se comportent de manière similaire aux pointeurs de tableau; la plupart de ce que vous savez sur l'arithmétique des pointeurs peut également être appliqué aux itérateurs vectoriels.

À partir de C ++ 11, vous pouvez utiliser std::distanceà la place de la soustraction pour les itérateurs et les pointeurs:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));
dasblinkenlight
la source
Pardon, je ne vois pas les commentaires de @Bob__, peut-être supprimés? Je me demande pourquoi ptrdiff_test mieux que size_tpuisque ptrdiff_t cela soulèverait un avertissement de comparaison entre un entier signé et non signé
Hiraku
3
@Hiraku Il a supprimé son commentaire. Il a suggéré d'utiliser ptrdiff_tparce qu'il vous permet de stocker la distance entre n'importe quelle paire d'itérateurs dans le même conteneur, même dans des situations où le résultat est négatif. Si nous utilisons, size_tnous devons faire attention à ne pas soustraire un itérateur plus grand d'un itérateur plus petit.
dasblinkenlight
Pour être plus précis, vous devez ajouter "#include <algorithm>" (pour utiliser std :: find). L'auteur de la question a également omis cet "inclure".
Grag2015
92

Si vous voulez un index, vous pouvez l'utiliser std::finden combinaison avec 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
la source
8
pourquoi ne pas utiliser const-iterators?
dani
-1

Je suis un débutant, voici donc une réponse pour débutants. Le if dans la boucle for donne i qui peut ensuite être utilisé selon les besoins, comme Nombres [i] dans un autre vecteur. La plupart est fluff pour des exemples, le pour / si dit vraiment tout.

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
la source