Як отримати положення певного елемента у векторі рядків, використовувати його як індекс у ints векторі?


99

Я намагаюся отримати індекс елемента у векторі strings, використовувати його як індекс в іншому intтипі вектора , чи це можливо?

Приклад:

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

Тепер я хочу , щоб отримати позицію old_nameв Namesвекторі, щоб використовувати його в отриманні доступу певного елемента в Numbersвекторі. Так що я можу сказати:

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

Я спробував використовувати:

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

але, очевидно, це не працює, оскільки posє тип рядка!


Я припускаю , що це повинно stackoverflow.com/questions/1425349 / ...
Francesco Vollero

Ви повинні перевірити std :: map або std :: unordered_map.
Etherealone

Відповіді:


158

Для отримання положення елемента у векторі, знаючи ітератор, що вказує на елемент, просто відніміть v.begin()від ітератора:

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

Тепер ви повинні перевірити posпроти , Names.size()щоб побачити , якщо він знаходиться поза межами чи ні:

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

векторні ітератори ведуть себе подібними до покажчиків масиву; більшість того, що ви знаєте про арифметику вказівника, можна застосувати і до векторних ітераторів.

Починаючи з C ++ 11, ви можете використовувати std::distanceзамість віднімання ітераторів, і покажчиків:

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

Вибачте, я не бачу коментарів @Bob__, можливо, видалено? Я задаюся питанням , чому ptrdiff_tце краще , ніж size_tтак ptrdiff_t би підняти попередження порівняння між підписом і цілого числа без знака
Hiraku

3
@Hiraku Він видав свій коментар. Він запропонував використовувати, ptrdiff_tоскільки він дозволяє зберігати відстань між будь-якою парою ітераторів в одному контейнері, навіть у ситуаціях, коли результат негативний. Якщо ми використовуємо, size_tми повинні бути обережними, щоб не відняти більший ітератор від меншого ітератора.
dasblinkenlight

Якщо точніше, вам слід додати "#include <алгоритм>" (для використання std :: find). Автор питання пропустив і це "включити".
Grag2015

92

Якщо ви хочете індекс, ви можете використовувати std::findв поєднанні з 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
чому б не використовувати const-iterators?
Дані

-1

Я початківець, ось ось відповідь для початківців. Цикл if в циклі for дає i, який потім можна використовувати, проте потрібні такі, як Numbers [i] в ​​іншому векторі. Більшість це пух заради прикладів, для / якщо насправді це все говорить.

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;
        }
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.