Проверьте возвращаемое значение lower_bound против конечного итератора - PullRequest
8 голосов
/ 05 января 2012

В действующем STL Скотта Мейерса (стр. 195) есть следующая строка:

"Результат lower_bound должен быть проверен, чтобы увидеть, указывает ли он на искомое значение. В отличие от find, вы не можете просто проверить возвращаемое значение lower_bound на конце итератора."

Может кто-нибудь объяснить, почему вы не можете этого сделать? кажется, работает нормально для меня.

1 Ответ

9 голосов
/ 05 января 2012

Он отлично работает для вас, потому что ваш элемент присутствует.

lower_bound возвращает итератор к первому элементу не менее , чем заданное значение, а upper_bound возвращает итераторна первый элемент больше заданного значения.

Учитывая массив 1, 2, 3, 3, 4, 6, 7, lower_bound(..., 5) вернет итератор, указывающий на 6.

Следовательно, два путипроверки наличия значения:

  • Используйте equal_range, чтобы также получить upper_bound (вычисления отдельно lower_bound и upper_bound, вероятно, будут неоптимальными).Если std::distance между границами больше 0, то элемент присутствует.

    1, 2, 3, 3, 4, 6, 7
    std::distance(std::lower_bound(v.begin(),v.end(),5), std::upper_bound(v.begin(),v.end(),5)) == 0 // 6 is absent
    std::distance(std::lower_bound(v.begin(),v.end(),3), std::upper_bound(v.begin(),v.end(),3)) == 2 // 3 is present
    
  • Сравните элемент, указанный итератором, с вашим значением (при условии, что операторы != и < согласованы), но вы должны убедиться, что он не возвращаетend iterator.

    *(std::lower_bound(v.begin(), v.end(), 5)) != 5
    

Кроме того, поскольку lower_bound - это алгоритмы двоичного поиска, было бы непоследовательным возвращать end, если элемент не был найден.Фактически, итераторы, возвращаемые этим алгоритмом, могут использоваться, например, в качестве подсказки для последующей операции вставки.

...