2012-09-07 22 views
7

multimap<string,string>'u kullanan bazı (çalışma) kodum var. Aynı tuştaki yinelenen değerleri reddetmek için değiştirmek istiyorum (aynı anahtardaki farklı olarak farklı değerler iyi, aksi halde bir multimap kullanmazdım).Yinelenen çiftleri nasıl önlerim/multimap'ta bir çifti nasıl bulurum?

Şaşırtıcı bir şekilde, çoğaltmaları önlemek için bir anahtar-değer çifti (yalnızca bir anahtar bulmak) bulmak için yerleşik bir yol olması için türün seem'u yoktur. Ama SO üzerinde birisinin hazır bir çözümü olması gerektiğini düşünüyorum. Kimse?

+0

Farklı anahtarlara sahip yinelenen değerler var mı? Birden çok kez kaç anahtar kullanılmasını beklerdiniz ve bu sıklıkta ne sıklıkta olur? – ypnos

+0

Elbette, farklı anahtarlarda aynı değer iyidir. Benim durumumda fan çıkışı küçüktür (genellikle anahtar başına 1 veya 2 değer), bu yüzden DeadMG'nin 'std :: map >' ye geçme önerisi etkili değildir (çünkü multimap tabanlı kod zaten yazılmıştır). – Qwertie

cevap

3

Burada ile geldi budur.)

+0

Döndürülen yineleyiciyi kullandığınız tek şey karşılaştırma ise, o zaman neden sadece 'boole' döndürmüyor? – jrok

+0

Kim bilir, bir gün 'map.erase (find_pair (...)) 'yapmak isteyebilirim. Bir includes_pair() sarıcı, kuşkusuz da kullanışlı olabilir. – Qwertie

1

Size önerim, bir multimap'ınızı bir sınıfa sarmak ve doğrulamayı, haritaya bir şey eklediğiniz yöntemde yapmaktır. Fonksiyonların geri kalanı sadece multimap yöntemlerine geçebilirdi. Çok sayıda kazan plaka kodu yapar, ancak başka tür doğrulamalar yapmanız gerekiyorsa, bu şekilde daha kolay olacaktır.

+0

Öneriniz O (N) zaman olacaktır. – Puppy

0

O

 std::set<std::pair<std::string,std::string>>> 

Aradığınız tam olarak özelliklerine sahip olacak gibi görünüyor. Ancak, bu bir harita ya da multimap değildir. Hem multimap hem de anahtar, değer çiftlerini ayarlayabilir veya sadece tutarlılığı kontrol etmek için bu seti oluşturabilirsiniz.

Bu seti kullanır ve çoklu arabirim arabiriminde bunun üzerinden bir bağdaştırıcı oluşturur. Belki de uygulamak en kolay çözüm değil, ancak en iyi performans verimliliğidir.

Referanslar için "adaptör tasarım deseni" konusuna bakın.


[GÜNCELLEME]

Bkz benim bir başlangıç ​​noktası olarak working example.

E.g. anahtar için tüm değerleri üzerinde yineleme nasıl - bkz:

typedef std::set<std::pair<std::string, std::string> > ssset; 

ssset::iterator get_key(ssset& s, std::string key) 
{ 
    ssset::iterator it = s.lower_bound(std::make_pair(key, "")); 
    if (it != s.end() && it->first == key) return it; 
    return s.end(); 
} 

for (ssset::iterator it = get_key(s, "abc"); it != s.end() && it->first == "abc"; ++it) 
    std::cout << it->first << "->" << it->second << std::endl; 
+0

Sorun şu ki, arama için bir çift gerekli olduğundan, bir anahtarla ilişkili değerleri/değerleri istemiyorum. – Qwertie

+0

Alt sınırını ("," ") arayabilirsiniz. Anahtar ile bulunursa ilk değerdir. Diğer anahtar başlayana kadar yineleyin. Bu adaptörde çevrilmiş olabilir – PiotrNycz

5

std::map<std::string, std::set<std::string>> özellikleriniz (alt karmaşıklığı rağmen unordered_map ve unordered_set) Aradığınız exactamondo sahip olduğu ortaya çıkacaktır. (Tek bir tuş eklenmiş değerlerin bir sayıda olduğunda bu verimli değildir, ama benim durumumda her tuş üzerinde çok az değerler vardır

template<class K, class V> 
typename multimap<K, V>::const_iterator find_pair(const multimap<K, V>& map, const pair<K, V>& pair) 
{ 
    typedef multimap<K, V>::const_iterator it; 
    std::pair<it,it> range = map.equal_range(pair.first); 
    for (it p = range.first; p != range.second; ++p) 
     if (p->second == pair.second) 
      return p; 
    return map.end(); 
} 
template<class K, class V> 
bool insert_if_not_present(multimap<K, V>& map, const pair<K, V>& pair) 
{ 
    if (find_pair(map, pair) == map.end()) { 
     map.insert(pair); 
     return true; 
    } 
    return false; 
} 

:

+0

bahsettim O birden fazla tuşa sahip olduğu için bir multimap kullanıyor. – Rapptz

+0

Ama ("a", ("a")) yapımınıza izin verilir ... – PiotrNycz

+0

harita ve multimap "a", "a" da izin verir. DeadMG'nin önerisi işe yarayabilir ama benim durumum için ideal değil (bkz. Yukarıdaki yorum ... özellikle C++ 03'de olduğum için -> kopya kurucular hakkında daha fazla endişe duyuyorum.) – Qwertie

İlgili konular