Як перевірити, чи містить std :: map ключ, не роблячи вставлення?


148

Єдиний спосіб , яким я знайшов , щоб перевірити наявність дублікатів, вставляючи і перевірку std::pair.secondдля false, але проблема полягає в тому , що це все ще вставляє що - то , якщо ключ не використовується, в той час як то , що я хочу , це map.contains(key);функція.


Відповіді:


305

Використання my_map.count( key ); він може повернути лише 0 або 1, що по суті є булевим результатом, який ви хочете.

По черзі також my_map.find( key ) != my_map.end()працює.


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

42
Ні, аргумент передчасної оптимізації справедливий лише в тому випадку, якщо оптимізація докладе певних зусиль, а в цьому випадку - не.
markh44

13
Неправда. Це не передчасно, якщо це полегшує читання коду або усуває зайві накладні витрати. У цьому випадку, якщо count () все-таки реалізується через find (), то виклик find () безпосередньо виключає виклик функції ... ergo, це зріла оптимізація. Я вважаю, що використання дзвінка find () також є більш очевидним, але це суто особисті переваги.
Тім Кітінг

9
Не передчасна оптимізація бути в курсі функцій бібліотеки, перш ніж сформувати звичку користуватися ними. У цьому випадку ви маєте рацію, це не має значення, але і незначна стилістична різниця між знаходженням і підрахунком. Я думаю, ви занадто далеко забираєте риторику "передчасної оптимізації". Вам слід скористатися будь-якими "безкоштовними" звичками оптимізації, які ви зможете знайти та використовувати їх для щоденного розвитку. Саме тоді, коли кодери піддаються пастці виплат витрат на читаність / час розробки / тощо, все для невимірних "підвищення продуктивності", що передчасна оптимізаційна риторика стає правильною порадою.
VoidStar

10
Далеко, std повинен просто додати проклятий 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
Звичайно, я розумію, що ОП не вкладає, тому lower_boundрішення, що базується, є надмірним. Я якось згадав свою відповідь "на повноту"; як я вже сказав, ваша цілком адекватна. :-)
Кріс Єстер-Янг

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

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

1
@Hunter Ти можеш показати мені свій код? Якщо вона не є масовою, я, певно, можу переглядати це для вас.
Кріс Єстер-Янг

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.