2011-01-24 16 views
13
std::vector<int> v = {1,2,3,4,5}; 
auto i = std::remove(v.begin(),v.end(),3); 
for(auto j = v.begin(); j!= v.end();++j) 
    std::cout << *j; 

वास्तविक उत्पादन: 12455ठीक से कार्य नहीं निकाल

कहाँ अतिरिक्त 5 से आता है?

वांछित उत्पादन: 1245

कैसे एक ही प्राप्त करने के लिए?

मैं वास्तव में वेक्टर के आकार बदलना चाहते हैं, इस सवाल का जवाब प्रसून सौरव द्वारा दिए गए सही लगती है

उत्तर

25

remove doesnt actually remove the elements

निकालें रेंज [first, last) सभी तत्वों value के बराबर हैं से निकाल देता है। यही है, रिटर्न को एक इटरेटर new_last रिटर्न हटा दें जैसे [first, new_last) में value के बराबर कोई तत्व नहीं है। 1[new_last, last) श्रेणी में पुनरावृत्त सभी अभी भी भरोसेमंद हैं, लेकिन वे तत्व जो वे इंगित करते हैं निर्दिष्ट हैं। निकालें जिसका अर्थ है कि तत्वों कि मूल्य के बराबर नहीं हैं के रिश्तेदार आदेश unchanged.`

std::remove एल्गोरिथ्म केवल आगे iterators की एक जोड़ी का उपयोग कर काम करता है और सामान्य रूप में अंतर्निहित कंटेनर के बारे में कुछ भी नहीं जानता है स्थिर है,।

आप यानी remove

auto i = std::remove(v.begin(),v.end(),3); 
v.erase(i,v.end()); 
for(auto j = v.begin(); j!= v.end();++j) 
    std::cout << *j; 
+4

@Rookie: पर कि 'निकालें()' फिर से फोन देखो। वह एल्गोरिदम एक अनुक्रम देखता है और इसमें कंटेनर तक पहुंच नहीं है, तो इससे कुछ भी कैसे हटा सकता है? – sbi

+2

"मिटाएं-हटाएं मुहावरे" - जिसे "नोट्स" में पृष्ठ के अंत में दिया जाता है। –

+2

@GMan: मेरा मतलब है कि आप अपना जवाब ऊपर उठाएं और मेरी उपरोक्त टिप्पणी हटा दें। आपने अपना जवाब क्यों हटा दिया? इसमें एक महत्वपूर्ण बिंदु है जिसे प्रसून ने नहीं बनाया था (अभी तक)। – sbi

2

remove रिटर्न नई अंत के साथ erase गठबंधन को erase-remove मुहावरा उपयोग करने के लिए वास्तव में तत्व निकाल जरूरत है। तो अपने कोड के ठीक यह है:

std::vector<int> v = {1,2,3,4,5}; 
auto newEnd = std::remove(v.begin(),v.end(),3);//return value stored in newEnd 
for(auto j = v.begin(); j!= newEnd ;++j) //note j!=newEnd 
    std::cout << *j; 

आउटपुट:

1245 

इसे बाहर अपने आप की जाँच करें: http://www.ideone.com/3AMD9

5

फिर std::remove के लिए दस्तावेज़ीकरण पढ़ें।

समारोह एक कंटेनर से तत्वों को दूर नहीं करता (यहां तक ​​कि पता नहीं वास्तव में, यह है कि एक कंटेनर शामिल है, के रूप में यह केवल iterators देखता है), यह केवल एक दृश्य में मान ले जाता है और एक नया इटरेटर वापसी i जैसे कि सभी अंतराल [ begin .. i [ में मूल ऑर्डर में सभी गैर-हटाए गए तत्व शामिल हैं। तत्वों [ i .. end [ में बचे अनिर्दिष्ट हैं, और यह एक कंटेनर से कि अंतराल को खत्म करने (यदि आप इसे की जरूरत है) आपकी जिम्मेदारी है:

auto i = std::remove(...); 
v.erase(i,v.end()); 

कारण है कि आप एक अतिरिक्त 5 है कि ठेठ हटाने एल्गोरिथ्म प्रतियां है हटाए गए मानों द्वारा छोड़े गए छेदों में मान, और i इटरेटर के मानों को कभी भी ओवरराइट नहीं किया जाता है, वे मूल अनुक्रम में समान रहते हैं।हालांकि, यह व्यवहार विश्वसनीय नहीं है - बस उन्हें पढ़ने के बिना i के मानों को खत्म करें।

-3

यह सीम है कि आप for() कथन में वेक्टर की एन + 1 स्थिति प्रिंट कर रहे हैं। यह होना चाहिए:

for(auto j = v.begin(); j!= v.end();j++) 
    std::cout << *j; 

j++ कोई ++j

+2

' for' लूप के संदर्भ में, 'j ++' और '++ j' बराबर हैं (हालांकि, इटरेटर के लिए, प्रदर्शन अंतर हो सकते हैं)। –

+0

इस संदर्भ में, 'j ++' और' ++ j' परिणाम एक ही व्यवहार में होते हैं। – xtofl

संबंधित मुद्दे