¿Cómo obtener la posición de un determinado elemento en el vector de cadenas, para usarlo como índice en el vector ints?

99

Estoy tratando de obtener el índice de un elemento en un vector de strings, para usarlo como índice en otro vector de inttipo, ¿es posible?

Ejemplo:

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

Ahora quiero obtener la posición de old_nameen el Namesvector, para usarlo para acceder a cierto elemento en el Numbersvector. Para que pueda decir:

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

Intenté usar:

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

pero obviamente esto no funciona ya que poses de tipo cadena.

Nour
fuente
Supongo que esto debería stackoverflow.com/questions/1425349/…
Francesco Vollero
Debería consultar std :: map o std :: unordered_map.
Etherealone

Respuestas:

158

Para obtener una posición de un elemento en un vector conociendo un iterador que apunta al elemento, simplemente reste v.begin()del iterador:

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

Ahora es necesario comprobar posen contra Names.size()para ver si está fuera de límites o no:

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

los iteradores vectoriales se comportan de manera similar a los punteros de matriz; la mayor parte de lo que sabe sobre aritmética de punteros también se puede aplicar a iteradores vectoriales.

A partir de C ++ 11, puede usar std::distanceen lugar de la resta tanto para iteradores como para punteros:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));
dasblinkenlight
fuente
Lo siento, no puedo ver los comentarios de @Bob__, ¿tal vez eliminados? Me pregunto por qué ptrdiff_tes mejor que size_tdesde que ptrdiff_t generaría una advertencia de comparación entre entero con y sin signo
Hiraku
3
@Hiraku Borró su comentario. Sugirió usarlo ptrdiff_tporque le permite almacenar la distancia entre cualquier par de iteradores en el mismo contenedor, incluso en situaciones en las que el resultado es negativo. Si usamos size_tdebemos tener cuidado de no restar un iterador más grande de un iterador más pequeño.
dasblinkenlight
Para ser más precisos, debe agregar "#include <algorithm>" (para usar std :: find). El autor de la pregunta también omitió este "incluir".
Grag2015
92

Si desea un índice, puede usarlo std::finden combinación 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);
}
juanchopanza
fuente
8
¿por qué no utilizar constantes-iteradores?
dani
-1

Soy un principiante, así que aquí hay una respuesta para principiantes. El if en el bucle for da i que luego se puede usar sin embargo, como sea necesario, como Números [i] en otro vector. La mayoría es pelusa, por ejemplo, el por / si realmente lo dice todo.

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
fuente