Как найти элемент в указанном диапазоне в std::map?

Есть ли эквивалентная версия std::find(first, last), но для std::map? То есть существует ли версия метода std::mapfind, который ищет элемент в map, но ограничивает поиск только указанным диапазоном [first, last)? В идеале решение должно быть логарифмическим размером [first, last).

Из что я видел сам std::map::find не поддерживает эту функцию (он всегда ищет по всей карте).

Может я что-то упускаю, но почему std::map::lower_bound вам не нравится?

SergeyA 21.02.2019 16:06

Вы можете уточнить свой пример std::find(v.begin(), v.end()), чтобы не звонить begin и end, а что-то вроде std::find(subrange_first, subrange_last);. Вы хотите что-то в O(log(distance(subrange_first, subrange_last))) не O(log(size(map))) и не O(distance(subrange_first, subrange_last))

Caleth 21.02.2019 16:27

@Калет Я согласен; это сбивало с толку. Я отредактировал его сейчас, пытаясь сделать его более ясным.

Anakhand 21.02.2019 16:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
3
1 318
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы можете использовать std::lower_bound, std::upper_bound или std::equal_range для этого, поскольку итераторы std::map и данные на карте удовлетворяют требованиям для этих функций, хотя вы должны знать, что это будет менее эффективно, чем std::map::find() из-за линейных приращений итератора.

От std::lower_boundдокументация

The number of comparisons performed is logarithmic in the distance between first and last (At most log 2(last - first) + O(1) comparisons). However, for non-LegacyRandomAccessIterators, the number of iterator increments is linear.

акцент мой.

Если я правильно понял вопрос, std::map::lower_bound это именно то, что вы ищете - оно дает вам элемент не меньше ключа. И на другом конце тоже есть upper_bound.

Это не отвечает на вопрос. искать себя должен быть ограничен [first, last) (и быть логарифмическим в std::distance(first, last)), а не возвращаемыми результатами. std::map::lower_bound не лучше, чем std::map::find в этом отношении.

Max Langhof 21.02.2019 16:09

@MaxLanghof Нет, ты ошибаешься. std::find даст вам элемент, если он есть на карте, в то время как lower_bound даст вам элемент только в том случае, если он не меньше, чем указанный в lower_bound. Вы должны пересмотреть свой отрицательный голос. Так что это точно так же, как std::find с границей.

SergeyA 21.02.2019 16:11

Ни то, ни другое не входит в вопрос. Опять же, речь идет об ограничении диапазона поиска, а не о том, как найти элемент на всей карте.

Max Langhof 21.02.2019 16:12
std::find и std::lower_bound являются ограничениями диапазона поиска. Вы явно неправильно понимаете вопрос.
SergeyA 21.02.2019 16:12
std::map::lower_bound есть ли у нет ограничения по диапазону поиска. Если вы хотите, чтобы ваш ответ был о std::lower_bound (а не std::map::lower_bound), не стесняйтесь изменить его соответствующим образом (но это уже покрыто ответом Славы).
Max Langhof 21.02.2019 16:14

Диапазон поиска @MaxLanghof и фильтрация результатов сортировки не могут быть различимы для стороннего наблюдателя. Наблюдаемое поведение такое же, метод поиска — деталь реализации.

SergeyA 21.02.2019 16:17

Сложность разная. Если у меня есть 2^N элементов на карте, то поиск всех из них занимает O(N). Если я знаю, что мой элемент находится в диапазоне [first, last) с std::distance(first, last) == N, то поиск должен быть выполним в O(log(N)). Как объясняется в ответе Славы, std::lower_bound (и друзья) позволяет вам делать это в O(log(N)) сравнениях, но O(N) увеличивается итератор.

Max Langhof 21.02.2019 16:18

@MaxLanghof Я совершенно не понимаю тебя. Поиск карты - O (log N).

SergeyA 21.02.2019 16:20

То же самое и с поиском в отсортированном диапазоне (из которого состоит std::map). Дело в том, что N карты и N диапазона для поиска могут (сильно) отличаться. Пожалуйста, взгляните на мой пример еще раз, где первое — 2^N, а второе — N.

Max Langhof 21.02.2019 16:21

@MaxLanghof это все еще намного лучше, чем ответ с наибольшим количеством голосов со сложностью O (N), поэтому с точки зрения производительности это лучшее, на что может надеяться ОП, и с точки зрения поведения это именно то, что им нужно. Я стою за своим ответом.

SergeyA 21.02.2019 16:24

Позвольте мне перефразировать. У меня есть карта с 1e20 элементами. Но я знаю, что элемент, который я ищу, находится в первых трех. Как я могу указать карте искать мой элемент в этом крошечном диапазоне без (двоичного) поиска по всем 1e20? Ваш ответ — O(log(elements_in_map)) (сравнения), тогда как принятый ответ — O(length_of_range) (приращения итератора). Нетрудно заметить, что есть случаи, когда length_of_range <= log(elements_in_map) (оба моих примера подробно описывают такие случаи). Не говоря уже о том, что приращения и сравнения итераторов могут иметь очень разные реальные затраты.

Max Langhof 21.02.2019 16:25

@MaxLanghof, если у вас есть элементы 2 ^ Н на карте, то поиск среди них всех (т. Е. std::map::lower_bound) занимает НА), правильно. Однако, если вы ограничите поиск только элементами Н из этих 2 ^ Н, std::lower_bound/std::upper_bound сможет нет сделать это в журнал (N), потому что итераторы std::map — это нетитераторы произвольного доступа.

ネロク 21.02.2019 16:31

@ElProfesor Я никогда не говорил обратного? Я четко указал O(log(N)) сравнения и O(N) итератор увеличивает при использовании std::lower_bound и т. д., при этом теоретический оптимум равно O(log(N)) для обоих. Я не совсем уверен в этом теоретическом оптимуме, но я никогда не говорил, что std::lower_bound было O(log(N)) вообще.

Max Langhof 21.02.2019 16:34

@MaxLanghof Ну, на первый взгляд не так ясно: тогда поиск должен быть выполним в O(log(N)), но вы правы, поскольку объяснили это сразу после этого предложения. Прости.

ネロク 21.02.2019 16:40

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