In std :: multiset gibt es eine Funktion oder einen Algorithmus, um nur ein Sample (unicate oder duplicate) zu löschen, wenn ein Element gefunden wird


83

Vielleicht ist dies ein Duplikat, aber ich habe keine Suche gefunden: Wenn erase(value)aufgerufen wird, werden std::multisetalle Elemente mit dem gefundenen Wert gelöscht. Die einzige Lösung, an die ich denken könnte, ist:

std::multiset<int>::iterator hit(mySet.find(5));
if (hit!= mySet.end()) mySet.erase(hit);

Das ist in Ordnung, aber ich dachte, es könnte besser sein. Irgendwelche Ideen ?


22
Dies ist ein durchaus vernünftiger Ansatz.
Templatetypedef

Stellt dieser Ansatz sicher, dass der angegebene Schlüssel ("5") doppelt vorhanden ist?
Arun

@ArunSaha: Nein. Aber wenn es kein Duplikat ist, möchte ich es trotzdem löschen. Durch die Antworten habe ich das Gefühl, dass es keine bessere Lösung gibt. Vielleicht war die Frage überhaupt dumm :-P
Martin

1
Für multimap: Gibt es eine Garantie dafür, welche Elemente findzurückgegeben werden? (Reihenfolge der Einfügung? Auch nach einer solchen Löschung? Implementierung abhängig?)
P Marecki

2
Ehrlich gesagt ist es eine so offensichtliche Gefahr bei der Verwendung von Multisets, die nicht zu den am häufigsten verwendeten Klassen gehören.
Predelnik

Antworten:


32
auto itr = my_multiset.find(value);
if(itr!=my_multiset.end()){
    my_multiset.erase(itr);
}

Ich würde mir vorstellen, dass es einen saubereren Weg gibt, dasselbe zu erreichen. Aber das erledigt den Job.


7
Dies unterscheidet sich nicht von dem, was in Frage kommt.
Troubadour

1
Genau! Macht keinen Sinn. 12 andere Leute haben etwas Nützliches in der Antwort gesehen, also weiß ich, dass ich nicht verrückt werde.
user2251346

6
Übersehen Sie niemals die Möglichkeit, dass Sie zusammen mit allen anderen verrückt werden :)
Apollys unterstützt Monica

15

Probier diese:

multiset<int> s;
s.erase(s.lower_bound(value));

Solange Sie sicherstellen können, dass die valueAusgänge im Set. Das funktioniert.


2
 if(my_multiset.find(key)!=my_multiset.end())
   my_multiset.erase(my_multiset.equal_range(key).first);

Dies ist der beste Weg, den ich mir vorstellen kann, um eine einzelne Instanz in einem Multiset in C ++ zu entfernen


1
Im Vergleich zu der Lösung, die ich in der Frage vorgeschlagen habe, führt Ihr Code zwei Suchvorgänge (find + same_range) anstelle einer ineffizienten durch
Martin

Da dies dieselbe Komplexität ist, gefällt mir diese Antwort sehr gut. Vielen Dank
Crystal

1

Ich würde folgendes versuchen.

Rufen Sie zuerst equal_range()auf, um den Bereich der Elemente zu ermitteln, die dem Schlüssel entsprechen.

Wenn der zurückgegebene Bereich nicht leer ist, dann erase()ein Bereich von Elementen (dh der, erase()der zwei Iteratoren benötigt), wobei:

  • Das erste Argument ist der Iterator für das zweite Element im zurückgegebenen Bereich (dh eine zurückgegebene Vergangenheit .first) und

  • das zweite Argument als das des zurückgegebenen Bereichspaar-Iterators .second.


Nach dem Lesen des Kommentars von templatetypedef (Danke!) Bearbeiten :

Wenn ein (im Gegensatz zu allen) Duplikat entfernt werden soll: Wenn das von zurückgegebene Paar equal_range()mindestens zwei Elemente enthält, erase()übergibt das erste Element das erste des zurückgegebenen Paares an eine einzelne Iteratorversion von erase():

Pseudocode:

pair<iterator, iterator> pit = mymultiset.equal_range( key );

if( distance( pit.first, pit.second ) >= 2 ) {
    mymultiset.erase( pit.first );
}

2
Ich denke, die Frage ist, nur ein Duplikat zu entfernen, nicht alle Duplikate.
Templatetypedef

Haben Sie eine Idee, ob dies schneller ist als meine Lösung und wenn ja, warum?
Martin

1

Das hat bei mir funktioniert:

multi_set.erase(multi_set.find(val));

wenn val im Multi-Set vorhanden ist.


0

Wir können so etwas tun:

multiset<int>::iterator it, it1;
it = myset.find(value);
it1 = it;
it1++;
myset.erase (it, it1);

1
Overkill. "Iterator zeigt auf ein einzelnes Element, das aus dem unordered_multiset entfernt werden soll."
Andrew

-3

In der Tat ist die richtige Antwort:

my_multiset.erase(my_multiset.find(value));

1
Wenn im Multiset kein Wert vorhanden ist, führt dies zu undefiniertem Verhalten .
kien_coi_1997
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.