Программирование >>  Операторы преобразования типа 

1 ... 28 29 30 [ 31 ] 32 33 34 ... 239


Поиск позиции элемента со значением, равным 3

* - такой элемент отсутствует, поэтому pos присваивается coll.endO */

pos = find Ccoll .beginC). coll.endO, Интервал

3); Значение

/* Перестановка злементов от найденного до конца интервала

* - поскольку итератор pos равен coll.endO.

* перестановка производится в пустом интервале. */

reverse (pos, coll.endO);

Поиск позиций со значениями 25 и 25

11st<int>::iterator pos25, pos35;

pQs25 = find (coll.beginC), coll.endO. Интервал

25): Значение

pos35 = find (coll.beginC). coll.endO. Интервал

35); Значение

/* Вывод максимума ло полученному интервалу

* - обратите внимание: интервап содержит позицию pos25.

* но позиция pos35 в него не включается. */

cout max: *max element Cpos25. pos35) endl:

process the elements including the last position cout max: *max element (pos25. ++pos35) endl;

В этом примере коллекция заполняется целыми числами от 20 до 40. После того как поиск элемента со значением 3 завершается неудачей, find() возврашает конец обработанного интервала - в данном случае coll.endO ~ и присваивает его переменной pos. Использование возвращаемого значения в качестве начала интервала при вызове reverse() не вызывает проблем, поскольку это приводит к следующему вызову:

reverse (coll.endO. coll.endO):

Происходит перестановка элементов в пустом интервале, поэтому никакие реальные действия не выполняются.

Но если алгоритм find() используется для определения первого и последнего элементов в подмножестве, следует помнить, что при определении интервала на основании полученных итераторов последний злемент исключается. Рассмотрим первый вызов max element():

max element Cpos25. pos35)

При этом вызове будет найдено максимальное значение 34 вместо 35:

max; 34



Чтобы включить в интервал последний найденный элемент, необходимо перевести итератор на одну позицию вперед:

fiiax elemGnt Cpos25. ++pos35)

На этот раз результат будет правильным:

шах: 35

В этом примере контейнером является список, поэтому для перевода pos35 к следующей позиции был применен оператор ++. Если бы мы использовали итератор произвольного доступа (как в случае вектора или дека), задача также решалась бы с помощью выражения pos35 + 1, поскольку итераторы произвольного доступа поддерживают математические операции (см. с. 105 и 261).

Конечно, итераторы pos25 и pos35 можно использовать для поиска в подмножестве элементов. Чтобы поиск производился с включением позиции pos35, следует сместить позицию итератора. Пример:

Увеличение pos35 для учета конца интервала при поиске ++POS35;

pos30 = find(pos25, pos35. Интервал 30); Значение

if Cpos30 == pQs35) {

cout 30 is NOT in the subrange endl:

else {

cout 30 1s in the subrange endl;

Bee примеры, приведенные в этом разделе, работают только потому, что нам точно известно: позиция pos25 предшествует позшдии pos35. В противном случае интервал [pos25, pos35) становится недействительным. Если вы не уверены в том, какой из элементов которому предшествует, то ситуация усложняется, а ошибка может привести к непредсказуемым последствиям.

Предположим, мы не знаем, что элемент со значением 25 предшествует элементу со значением 35. Более того, нельзя исключать, что одно или оба значения отсутствуют в контейнере. При использовании итератора произвольного доступа проверка выполняется оператором <<:

if (pos25 < ро535) {

Действителен интервал [pas25.pos35)

else if Cpos35 < pos25) {

Действителен интервал [pos35.pQs25)

else {

Итераторы равны; следовательно, оба итератора находятся в позиции end()



Без итераторов произвольного доступа не существует простого н быстрого способа определить порядок следования итераторов. Единственное разумное решение - провести поиск одного итератора в интервале от начала до другогс итератора или от другого итератора до конца, В этом случае алгоритм слегка изменяется: вместо того чтобы искать оба значения во всем исходном интервале, мы пытаемся определить, какое значение встречается первым. Пример:

pos25 = find Ccoll .beginO. coll.endO. Интервал 25); Значение

pos35 = find Ccoll .beginO. pos25. Интервал

35): Значение

if Cpo535 != pos25) {

/* pos35 лредшествует po£25: следовательно. * действителен только интервал [pos35.pos25) */

else {

pQs35 = find Cpos25. coll.endO. Интервал 35); Значение

if Cpos35 !- pos25) {

/* pQs25 лредшествует pos35; следовательно. * действителен только интервал [pos25.pos35) */

else {

Итераторы равны; следовательно, оба итератора находятся в позиции endC)

В отличие от предыдущей версии поиск значения 35 производится не во всем множестве элементов colL Сначала поиск ведется от начала до pos25. Если значение не найдено, поиск производится среди элементов, находящихся после pos25. В результате мы выясняем, какой итератор встречается раньше и какой интервал действителен.

Эффективность подобной реализации оставляет желать лучшего. Более эффективный способ найти первый элемент со значением 25 или 35 заключается в том, чтобы поиск выполнялся именно по такому условию. Для этого придется задействовать некоторые возможности STL, еще не упоминавшиеся в книге:

pos = find if Ccoll.beginO. coll.endO. Интервал

compQse f gx hx(logical or<bool>0. Критерий bind2ndCequal tQ<int>0.25). bind2nd(equal to<int>C).35)));

switch C*pos) { case 25:

Первым обнаружен элемент со значением 25



1 ... 28 29 30 [ 31 ] 32 33 34 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика