Std में: मल्टीसेट एक तत्व है यदि कोई तत्व पाया जाता है तो सिर्फ एक नमूना (अकुशल या डुप्लिकेट) को मिटाने के लिए एक फ़ंक्शन या एल्गोरिथ्म है


82

शायद यह एक डुप्लिकेट है, लेकिन मुझे कुछ भी खोजने में नहीं मिला: जब सभी तत्वों erase(value)पर कॉल किया जाता है std::multiset, तो पाया गया मूल्य हटा दिया जाता है। एकमात्र उपाय जो मैं सोच सकता था, वह है:

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

यह ठीक है, लेकिन मुझे लगा कि बेहतर हो सकता है। कोई विचार ?


22
यह पूरी तरह से उचित दृष्टिकोण है।
templatetypedef

क्या यह दृष्टिकोण सुनिश्चित करता है कि दी गई कुंजी ("5") डुप्लिकेट है?
अरुण

@ArunSaha: नहीं, लेकिन अगर इसकी डुप्लिकेट नहीं है, तो मैं इसे किसी भी तरह से हटाना चाहता हूं। मुझे जो उत्तर मिले, उनसे मुझे यह अहसास होता है कि कोई बेहतर उपाय नहीं है। हो सकता है कि यह सवाल पहली बार में बेवकूफी भरा था :-P
मार्टिन

1
के लिए multimap: क्या कोई गारंटी है कि कौन से तत्व findवापस आते हैं? (सम्मिलन का आदेश? इस तरह के
उन्मूलन के

2
ईमानदारी से यह मल्टीसैट का उपयोग करते समय एक ऐसी अविकसित स्थिति है जो सबसे अधिक बार उपयोग किए जाने वाले वर्गों में से नहीं है।
प्रेडेलनिक

जवाबों:


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

मुझे लगता है कि वहाँ एक ही पूरा करने का एक क्लीनर तरीका है। लेकिन इससे काम हो जाता है।


8
यह कोई अलग नहीं है कि प्रश्न में क्या है।
Troubadour

1
मैं सहमत हूँ! कोई मतलब नहीं है। 12 अन्य लोगों ने उत्तर में कुछ उपयोगी देखा तो मुझे पता है कि मैं पागल नहीं हूं।
user2251346

6
कभी भी इस संभावना को नजरअंदाज न करें कि आप हर किसी के साथ पागल हो रहे हैं :)
अपोलिस

16

इसको आजमाओ:

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

जब तक आप यह सुनिश्चित कर सकते हैं कि valueसेट में बाहर निकलता है। यह काम करता है।


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

यह सबसे अच्छा तरीका है जो मैं c ++ में एक मल्टीसेट में एक एकल उदाहरण को हटाने के बारे में सोच सकता हूं


1
प्रश्न के प्रस्तावित समाधान की तुलना में आपके कोड में दो के बजाय दो खोजें (खोजें + बराबर_रेंज) है जो अक्षम है
मार्टिन

जैसा कि यह एक ही जटिलता है, मुझे यह उत्तर बहुत पसंद है। धन्यवाद
क्रिस्टल

1

मैं निम्नलिखित की कोशिश करूँगा।

सबसे पहले equal_range()कुंजी के बराबर तत्वों की श्रेणी को खोजने के लिए कॉल करें ।

यदि दी गई सीमा गैर-रिक्त है, तो erase()तत्वों की एक श्रेणी (यानी erase()जो दो पुनरावृत्तियों को लेती है):

  • पहला तर्क लौटे रेंज (यानी एक अतीत .firstलौटा) और में 2 तत्व के लिए पुनरावृत्ति है

  • लौटे रेंज जोड़ी iterator के रूप में दूसरा तर्क .second


पढ़ने के बाद संपादित templatetypedef की टिप्पणी (धन्यवाद!):

यदि एक (सभी के विपरीत) डुप्लिकेट को हटा दिया जाता है: यदि जोड़ी द्वारा लौटाए गए equal_range()कम से कम दो तत्व हैं, तो erase()पहला तत्व एकल जोड़ीर संस्करण के लौटे जोड़े के .first पास करके erase():

छद्म कोड:

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

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

2
मुझे लगता है कि सवाल केवल एक डुप्लिकेट को खत्म करने के बारे में पूछ रहा है, सभी डुप्लिकेट नहीं।
templatetypedef

एक विचार है कि क्या यह मेरे समाधान से तेज है और यदि हाँ तो क्यों?
मार्टिन

1

यह मेरे लिए काम किया:

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

अगर बहु-सेट में वैल मौजूद है।


0

हम ऐसा कुछ कर सकते हैं:

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

1
Overkill। "मैं एक एकल तत्व की ओर इशारा करता हूं जिसे unordered_multiset से हटाया जाना है।"
एंड्रयू

0
 auto itr=ms.find(value);  
  while(*itr==value){
  ms.erase(value);
  itr=ms.find(value);  
  }

इसे आज़माएं यह मल्टीसेट में उपलब्ध सभी डुप्लिकेट को हटा देगा।


-3

वास्तव में, सही उत्तर है:

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

1
यदि मान मल्टीसेट में मौजूद नहीं है, तो यह अपरिभाषित व्यवहार का कारण बनता है
kien_coi_1997
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.