Возвращает ли low_bound() один и тот же результат с обратными итераторами вектора в порядке возрастания и прямыми итераторами вектора в порядке убывания?

Если у меня есть 2 вектора, один в порядке возрастания, а другой в порядке убывания:

vector<int> inc{1,2,3,4,6,7}, dec{7,6,4,3,2,1};

Всегда ли следующие два выражения дают один и тот же результат? Или есть ли разница в их работе?

lower_bound(inc.rbegin(), inc.rend(), some_number, greater<int>()) // #1
lower_bound(dec.begin(), dec.end(), some_number, greater<int>()) // #2

Я чувствую, что они одинаковые, но во время недавнего конкурса на Codeforces один был принят, а другой нет.

Вы уже консультировались с cppreference? std::lower_bound и std::upper_bound. Если да, то что вам еще неясно? И каков результат вашего кода? Вы пробовали на своем компьютере?

Pepijn Kramer 15.08.2024 22:05

@PepijnKramer Да, я это сделал... но, как я уже сказал, по моему мнению, они должны быть семантически эквивалентны, но во время недавнего контента на Codeforces один был принят, а другой нет. Пожалуйста, дайте мне знать, если я что-то упускаю. Спасибо!

SHUBHAM KUMAR 15.08.2024 22:07

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

Igor Tandetnik 15.08.2024 22:10

@IgorTandetnik Да, я понимаю, что он создает обратный итератор ... но кроме того, если я просто использую элемент, на который указывает этот возвращаемый указатель, всегда ли мы получаем один и тот же результат?

SHUBHAM KUMAR 15.08.2024 22:14

Честно говоря, я не ожидал разницы и не могу воспроизвести: onlinegdb.com/IT3xVq-5E (возможно, вам стоит показать больше кода, возможно, проблема где-то в другом месте)

Pepijn Kramer 15.08.2024 22:14

Я вполне уверен, что (r1==inc.rend() && r2=dec.end) || *r1 == *r2 всегда должно быть четко определенным и истинным, если вы об этом.

Igor Tandetnik 15.08.2024 22:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С точки зрения алгоритма, std::lower_bounds, нет никакой разницы, кроме типа итератора (один — обратный итератор, а другой — нет), но его это не волнует.

В обоих случаях он выполнит одни и те же алгоритмические шаги и вернет итератор, указывающий на элемент, который в обоих случаях несет одно и то же значение, или итератор end()/rend().

Единственное незначительное отличие может заключаться в скорости. Я ожидал, что версия, использующая обратные итераторы, будет немного медленнее, но я не измерял.

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


Ради интереса, вот измерения быстрой скамьи для двух версий. Вы можете поиграть с диапазонами, чтобы увидеть, повлияет ли это на результат и если да, то каким образом. Чем ниже планка, тем быстрее. Синий цвет соответствует обратному итератору, а желтый — обычному итератору.

Вы намекаете на тот факт, что обратный итератор потребует некоторых дополнительных механизмов в коде (поэтому увеличение карт обратного итератора приведет к переходу назад по элементам вектора). При оптимизированной сборке я бы не ожидал какой-либо существенной разницы в производительности, и «не исключено», что производительность не будет иметь измеримой разницы.

Peter 16.08.2024 03:44

@Питер Да, во всем этом. Неизвестно, пока не измеришь. Я добавил тест к ответу. В clang версия обратного итератора работает намного медленнее. В gcc не так сильно, но все же заметно.

Ted Lyngmo 16.08.2024 07:32

Другие вопросы по теме