Как получить позицию определенного элемента в векторе строк, чтобы использовать его в качестве индекса в векторе ints?

100

Я пытаюсь получить индекс элемента в векторе 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имеет тип строки!

Nour
источник
Думаю, это должно быть stackoverflow.com/questions/1425349/…
Франческо Воллеро,
Вы должны проверить std :: map или std :: unordered_map.
Etherealone

Ответы:

159

Чтобы получить позицию элемента в векторе, зная итератор, указывающий на элемент, просто вычтите 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_));
dasblinkenlight
источник
Извините, я не вижу комментарии @Bob__, может быть, они удалены? Я задаюсь вопросом , почему ptrdiff_tэто лучше , чем size_tтак ptrdiff_t бы поднять предупреждение сравнения между подписью и целого числа без знака
Hiraku
3
@Hiraku Он удалил свой комментарий. Он предложил использовать, ptrdiff_tпотому что он позволяет хранить расстояние между любой парой итераторов в одном контейнере даже в ситуациях, когда результат отрицательный. Если мы используем, size_tмы должны быть осторожны, чтобы не вычесть больший итератор из меньшего итератора.
dasblinkenlight
Чтобы быть более точным, вы должны добавить "#include <algorithm>" (для использования 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);
}
Juanchopanza
источник
8
почему бы не использовать констант-итераторы?
dani
-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;
        }
    }
javer
источник