Как проверить, содержит ли std :: map ключ без вставки?


148

Единственный способ, который я нашел для проверки на наличие дубликатов, - это вставка и проверка std::pair.secondfor false, но проблема в том, что он по-прежнему вставляет что-то, если ключ не используется, тогда как мне нужна map.contains(key);функция.


Ответы:


305

Использование my_map.count( key ); он может возвращать только 0 или 1, что, по сути, является желаемым логическим результатом.

Поочередно my_map.find( key ) != my_map.end()работает тоже.


40
@ Джон: Это пахнет преждевременной оптимизации. На GCC (и я уверен, что самые разумные системы), map::countреализован как find(__x) == end() ? 0 : 1;. Для multimapвас может быть аргумент производительности, но это не вопрос OP, и я все еще предпочитаю элегантность.
Potatoswatter

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

13
Не правда. Это не преждевременно, если это облегчает чтение кода или устраняет ненужные накладные расходы. В этом случае, если count () так или иначе реализован через find (), то вызов find () напрямую устраняет вызов функции ... ergo, это зрелая оптимизация. Я считаю, что использование вызова find () также более очевидно, но это чисто личное предпочтение.
Тим Китинг

9
Это не преждевременная оптимизация - знать о функциях библиотеки, прежде чем вы привыкнете их использовать. В этом случае вы правы, это не имеет значения, но не имеет значения и незначительная стилистическая разница между поиском и подсчетом. Я думаю, вы слишком далеко зашли о риторике «преждевременной оптимизации». Вы должны использовать любые «бесплатные» привычки оптимизации, которые вы можете найти, и использовать их для повседневной разработки. Когда кодировщики преждевременной оптимизации становятся правильным советом, когда кодировщики поддаются ловушке оплаты затрат на удобочитаемость / время разработки / и т. Д., И все это за неизмеримое «повышение производительности».
VoidStar

10
Вне всяких сомнений, стандартному стандарту следует просто добавить чертовски has(k)/ contains(k)как и любой другой класс вменяемых карт на планете. Плохой дизайн интерфейса. Подход find () слишком многословен, и этот count(k)подход явно не соответствует семантическому равенству has(k). В этом отношении ни один не является find(k). Проверьте количество просмотров по этому вопросу.
Джаррод Смит

46

Potatoswatter ответ хорошо, но я предпочитаю использовать findили lower_boundвместо. lower_boundЭто особенно полезно, потому что возвращенный итератор может впоследствии использоваться для подсказки, если вы хотите вставить что-то с тем же ключом.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

Это немного отличается от того, как он говорит, что делает это ... единственное отличие состоит в том, что вычисления valueмогут быть пропущены, если вставка не нужна.
Potatoswatter

1
Конечно, я понимаю, что OP не хочет вставлять, поэтому lower_boundрешение на основе является излишним. Я только что упомянул свой ответ "для полноты"; Как я уже сказал, ваш вполне адекватен. :-)
Крис Шестер-Янг

4
Да, это хороший ответ, и я ни с чем не согласен. Просто указывает на отношение к альтернативе insertаприори. На самом деле, есть еще одно различие , если с помощью multimap, то lower_boundметод вставки в начале эквивалентного диапазона , тогда как обычный insertметод добавляет к концу диапазона.
Potatoswatter

2
Не ответ на вопрос, но мой плохой вопрос приводит меня к правильному ответу здесь ... Мне нужно сделать вставку / обновление. : D
Охотник-Орионнуар

1
@Hunter Можете ли вы показать мне свой код? Если это не массивно, я, вероятно, могу рассмотреть это для вас.
Крис Шутер-Янг

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.