Jak uzyskać pozycję określonego elementu w wektorze ciągów, aby użyć go jako indeksu w wektorze ints?

99

Próbuję uzyskać indeks elementu w wektorze strings, aby użyć go jako indeksu w innym wektorze inttypu, czy jest to możliwe?

Przykład:

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

Teraz chcę uzyskać położenie old_namew Nameswektorze, aby użyć go w dostępie do określonego elementu w Numberswektorze. Więc mogę powiedzieć:

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

Próbowałem użyć:

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

ale oczywiście to nie działa, ponieważ posjest typu string!

Nour
źródło
Myślę, że to powinno stackoverflow.com/questions/1425349/ ...
Francesco Vollero
Powinieneś sprawdzić std :: map lub std :: unordered_map.
Etherealone

Odpowiedzi:

158

Aby uzyskać pozycję elementu w wektorze, znając iterator wskazujący na element, po prostu odejmij v.begin()od iteratora:

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

Teraz trzeba sprawdzić posprzed Names.size()sprawdzić, czy to jest poza zakresem lub nie:

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

Iteratory wektorów zachowują się podobnie do wskaźników tablicowych; większość tego, co wiesz o arytmetyce wskaźników, można zastosować również do iteratorów wektorów.

Począwszy od C ++ 11, możesz używać std::distancezamiast odejmowania zarówno dla iteratorów, jak i wskaźników:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));
dasblinkenlight
źródło
Przepraszam, nie widzę komentarzy @Bob__, może zostały usunięte? Zastanawiam się, dlaczego ptrdiff_tlepiej niż size_todkąd ptrdiff_t podniosłoby ostrzeżenie o porównaniu między liczbą całkowitą ze
znakiem
3
@Hiraku Usunął swój komentarz. Zasugerował użycie, ptrdiff_tponieważ umożliwia przechowywanie odległości między dowolnymi parami iteratorów w tym samym pojemniku, nawet w sytuacjach, gdy wynik jest ujemny. Jeśli używamy size_t, musimy uważać, aby nie odjąć większego iteratora od mniejszego iteratora.
dasblinkenlight
Aby być bardziej precyzyjnym, należy dodać „#include <algorithm>” (aby użyć std :: find). Autor pytania również pominął to „uwzględnij”.
Grag2015
92

Jeśli chcesz mieć indeks, możesz użyć go std::findw połączeniu z 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
źródło
8
dlaczego nie użyć stałych iteratorów?
dani,
-1

Jestem początkującym, więc oto odpowiedź dla początkujących. Jeśli w pętli for daje i, które może być następnie użyte, jakkolwiek potrzebne, takie jak Numbers [i] w innym wektorze. Większość jest puszystą na przykład, for / if naprawdę mówi wszystko.

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
źródło