2016-01-10 3 views
-1

В C++ я знаю, что вы можете иметь несколько итераторов. Например, если у вас есть функция, которая хотела, чтобы увидеть первое совпадение строки в двух итераторах, почему бы код выглядеть примерно так:Ищет строку в двух итераторах в C++

Iterator found_it(Iterator one, Iterator two){ 
while(one != two && (*one) != "Bob"){ 
    one++; 
} 
return one; 
} 

* Вопрос сказал один и два не обязательно означают, начать() и конец() - это то, что действительно дал мне ум **** и растерянность: S *

во-первых, то, что происходит, если Bob был в итератора two? Потому что вы возвращаете только итератор one? Это то, что меня действительно смущает в данный момент.

Благодаря

+0

Где вы взяли этот код, как вы думаете, он намерен делать, и почему вы доверяете? – Beta

+0

В вашем примере итератор 'two' является итератором для элемента AFTER последнего элемента, который вы хотите найти. Поэтому даже не нужно ничего указывать. Это часто, например, 'std :: vector.end()'. – Rames

+3

Если «Боб» находится в итераторе два, то он выходит за пределы диапазона, который вы хотите найти, чтобы его не найти. Второй итератор - это * одно прошлое * диапазон поиска. Таким образом, вы ищете от «одного» до, но не включая «два». – Galik

ответ

0

Если «Боб» находится в итераторе два то из диапазона, который вы хотите найти, поэтому он не должен быть найден. Второй итератор один минута диапазон поиска.

Итак, вы ищете от one до, но не включая, two.

Если вы хотите найти в весь контейнер то вы пройдете begin() и end() в качестве аргументов для one и two. Но итераторы дают вам возможность искать промежуточные диапазоны в контейнере .

Например, что, если вы хотите найти все бобы?

std::vector<std::string> names {"Tim", "Beryl", "Bob", "Danny", "Bob", "Lou"}; 

Вы можете получить первый так:

auto bob1 = fond_it(names.begin(), names.end()); 

Вы можете получить второй, как это:

auto bob2 = fond_it(bob1 + 1, names.end()); 

Уведомление вы можете начать поиск на полпути через использование bob1 а не в начале.

+1

Кроме того, некоторые итераторы вообще не имеют дело с контейнерами. Например, 'std :: istream_iterator'. –

+0

Я вижу! Я понимаю, теперь думаю. Поэтому в основном, если мне задают вопрос о поиске элемента в диапазоне (x, y), где 'x' и' y' являются итераторами, это означает, что 'x' эквивалентен словам' container.begin() 'и' y' эквивалентно 'container.end() + 1' - т.е. вне области? Являются ли итераторы (несколько итераторов), в частности, для нескольких контейнеров? –

+0

@SamuelKielsfierou Well 'container.end()' is * уже * вне области видимости, потому что 'container.end()' указывает ** вне ** контейнер (по одной позиции). Ваш * алгоритм * в 'find_it()' ищет каждый элемент * container *, который * итераторы * указывают на элемент, на который указывает 'one', но ** не **, включая элемент, на который указывает' two'. – Galik

0

и two - это начало и конец (действительно только за пределами) диапазона, который вы хотите найти. Это может быть не то же самое, что и begin() и end() на контейнере, если вы хотите выполнить поиск только поддиапазона или если итераторы не поступают из контейнера вообще.

Отметьте, что one изменяется в пределах цикла; вы не обязательно возвращаете исходное значение one.

Ваша функция может быть переписана эквивалентно следующим образом:

Iterator found_it(Iterator begin, Iterator end) { 
    Iterator current = begin; 
    while (current != end && (*current) != "Bob"){ 
    current++; 
    } 
    return current; 
} 
+0

Я вижу, это имеет смысл. Итак, если было найдено значение 'Bob' - что будет возвращено? –

+0

Значение итератора, которое «указывает на« Боб ». –

1

Когда два итератора, используемые в качестве диапазона для функции или стандартного алгоритма, то второй итератор не входит в диапазон.То есть вы должны рассмотреть диапазон как

[first, last) 

Если функция или алгоритм как std::find возвращает вторые итераторы, то это означает, что диапазон не содержит целевое значение.

Если второй итератор был включен в диапазон, возникает вопрос, какой итератор должен возвращать, когда целевое значение не найдено?

Рассмотрим, например, собственные функции со следующими призывами

template <class Iterator> 
Iterator found_it(Iterator one, Iterator two){ 
while(one != two && (*one) != "Bob"){ 
    one++; 
} 
return one; 
} 

//... 

std::vector<std::string> v1 = { "Mary", "Bob" }; 
std::vector<std::string> v2 = { "Mary", "Peter" }; 

auto it1 = found_it(v1.begin(), v1.end()); 

if (it1 != v1.end()) std::cout << *it1 << " is present in v1" << std::endl; 
else std::cout << "Bob" << " is not present in v1" << std::endl; 

auto it2 = found_it(v2.begin(), v2.end()); 

if (it2 != v2.end()) std::cout << *it2 << " is present in v2" << std::endl; 
else std::cout << "Bob" << " is not present in v2" << std::endl; 
Смежные вопросы