Std :: map'nin ekleme yapmadan bir anahtar içerip içermediğini nasıl kontrol edebilirim?


148

Ben çoğaltmaları denetlemek bulduk tek yolu ekleme ve kontrol etmektir std::pair.secondiçin false, ama sorun anahtarı kullanılmayan ise istediğim şey bir oysa bu hala bir şey ekler olmasıdır map.contains(key);işlevi.


Yanıtlar:


305

Kullanın my_map.count( key ); yalnızca 0 veya 1 değerini döndürebilir, bu da aslında istediğiniz Boole sonucudur.

Alternatif olarak da my_map.find( key ) != my_map.end()çalışır.


40
@John: Bu, erken optimizasyondan kaynaklanıyor. GCC (ve eminim en makul sistemleri) map::countolarak uygulanır find(__x) == end() ? 0 : 1;. Çünkü multimapbir performans argümanınız olabilir, ama bu OP'nin sorusu değil ve yine de zarafeti tercih ediyorum.
Potatoswatter

42
Hayır, erken optimizasyon argümanı yalnızca optimizasyon bu durumda çalışmadığı için biraz çaba gerektiriyorsa geçerlidir.
markh44

13
Doğru değil. Kodun okunmasını kolaylaştırır veya gereksiz ek yükü ortadan kaldırırsa erken değildir. Bu durumda, count () zaten find () ile uygulanırsa, find () öğesini çağırmak doğrudan bir işlev çağrısını ortadan kaldırır ... ergo, bu olgun optimizasyonudur. Find () çağrısını kullanmanın da daha açık olduğunu, ancak tamamen kişisel tercih olduğunu düşünüyorum.
Tim Keating

9
Bunları kullanmayı alışkanlık haline getirmeden önce kütüphane işlevlerinin mükemmelliğinin farkında olmak erken bir optimizasyon değildir. Bu durumda haklısınız, önemli değil, ama bul ve say arasındaki ufak tefek üslup farkı da yok. Bence 'erken optimizasyon' söylemini çok ileri götürüyorsunuz. Bulabileceğiniz "ücretsiz" optimizasyon alışkanlıklarını almalı ve günlük gelişim için kullanmalısınız. Kodlayıcılar okunabilirlik / geliştirme zamanı / vb. Maliyetlerin ödenmesi tuzağına düştüklerinde, hepsi ölçülmemiş "performans kazanımları" için erken optimizasyon söylemi vermek için doğru tavsiye olur.
VoidStar

10
Uzak, std sadece gezegendeki diğer tüm aklı başında harita sınıfları gibi bir lanet has(k)/ contains(k)gibi eklemelidir . Kötü arayüz tasarımı. Find () yaklaşımı çok ayrıntılıdır ve count(k)yaklaşım kesinlikle semantik eşitlikte değildir has(k). Çünkü bu da değil find(k). Bu sorudaki görünüm sayısına göz atın.
Jarrod Smith

46

Potatoswatter cevabı tamam, ama kullanmayı tercih findveya lower_boundonun yerine. lower_boundözellikle yararlıdır, çünkü aynı anahtarla bir şeyler eklemek isterseniz, döndürülen yineleyici daha sonra ima edilen bir ekleme için kullanılabilir.

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
}

Bu, yaptığı şeyi açıkça farklıdır… tek fark valueekleme işleminin gereksiz olması durumunda hesaplamanın atlanabilmesidir.
Potatoswatter

1
Elbette, OP'nin yerleştirmeyi umursamadığını anlıyorum, bu yüzden lower_boundtemelli bir çözüm aşırı derecede. Az önce "bütünlük için" cevabımdan bahsettim; Dediğim gibi seninki yeterli. :-)
Chris Jester-Young

4
Evet, bu iyi bir cevap ve hiçbir şeye katılmıyorum. Sadece inserta priori alternatifi ile olan ilişkisine dikkat çekmek . Aslında, bir kullanan başka bir fark vardır multimap, lower_bounddüz ise eşdeğer aralığının başlangıcında yöntem uçlar insertyöntem aralığının sonuna eklenir.
Potatoswatter

2
Sorunun cevabı değil, ama soran zayıf sorum beni burada doğru cevaba götürüyor ... Ekleme / güncelleme yapmam gerekiyor. : D
Hunter-Orionnoir

1
@Hunter bana kodunu gösterebilir misin? Büyük değilse, muhtemelen sizin için inceleyebilirim.
Chris Jester-Young

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.