2012-01-29 21 views
12

मैंने स्ट्रिंग के वेक्टर के माध्यम से चलाने के लिए एक फ़ंक्शन बनाया है और लंबाई 3 या उससे कम की किसी स्ट्रिंग को हटा दिया है। यह एसटीएल एल्गोरिदम पुस्तकालय का उपयोग करने में एक सबक है।मिटाएं() को हटाने के बाद()

मुझे इस बात में परेशानी हो रही है कि कार्य कार्य करते हैं लेकिन न केवल यह लंबाई 3 या उससे कम की तारों को हटाता है बल्कि यह अंत में स्ट्रिंग "वेक्टर" को भी जोड़ता है।

उत्पादन

This test vector 

होना चाहिए और इसके बजाय यह

This test vector vector" 

है मैं इसे कैसे ठीक कर सकते हैं?

/* 
* using remove_if and custom call back function, write RemoveShortWords 
* that accepts a vector<string> and removes all strings of length 3 or 
* less from it. *shoot for 2 lines of code in functions. 
*/ 

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <vector> 
#include <iterator> 
using namespace std; 

bool StringLengthTest(string test) //test condition for remove_if algo. 
{ 
    return test.length() <= 3; 
} 

void RemoveShortWords(vector<string> &myVector) 
{ 
    //erase anything in vector with length <= 3 
    myVector.erase(remove_if(myVector.begin(), 
          myVector.end(), 
          StringLengthTest)); 
} 

int main() 
{ 
    //add some strings to vector 
    vector<string> myVector; 
    myVector.push_back("This"); 
    myVector.push_back("is"); 
    myVector.push_back("a"); 
    myVector.push_back("test"); 
    myVector.push_back("vector"); 

    //print out contents of myVector (debugging) 
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," ")); 
    cout << endl; //flush the stream 

    RemoveShortWords(myVector); //remove words with length <= 3 

    //print out myVector (debugging) 
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," ")); 
    cout << endl; 

    system("pause"); 
    return 0; 
} 

उत्तर

23

यह इस को समझने के लिए सबसे आसान है:

auto iter(remove_if(myVector.begin(), myVector.end(), StringLengthTest)); 
myVector.erase(iter); 

इन 2 लाइनों भी ऐसा ही आपकी एकल रेखा के रूप में। और अब यह स्पष्ट होना चाहिए कि "बग" क्या है। remove_if, पहले काम करता है। यह पूरे वेक्टर पर फिर से चलाता है और सभी "चयनित" प्रविष्टियों को "अंत तक" चलाता है (बेहतर कहा जाता है: यह गैर चयनित प्रविष्टियों को आगे बढ़ता है)। यह प्रविष्टियों से अधिक छोड़ दिया की "पिछले" स्थिति के लिए एक iterator देता है समाप्त हो गया है के बाद, कुछ की तरह:

इस
परीक्षण
वेक्टर
परीक्षण < - इटरेटर यहाँ अंक
वेक्टर

फिर आप एक ही इटरेटर के साथ मिटाना चलाते हैं। इसका मतलब है कि आप एक तत्व को इंगित करते हैं - ताकि आप "परीक्षण" तत्व मिटा दें। - जो कुछ आप देख रहे हैं उस पर क्या बचा है।

यह बस() वेक्टर समाप्त करने के लिए remove_if द्वारा लौटाए .:

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest), myVector.end()); //erase anything in vector with length <= 3 
+0

महान विवरण। क्या हो रहा है यह स्पष्ट करने के लिए बहुत बहुत धन्यवाद! – MCP

+2

यदि 'myVector' खाली था तो यह और भी अधिक काट देगा। फिर 'iter' 'myVector.end()' के बराबर होगा, और' मिटाएं (iter) 'का उपयोग करके मिटाना यूबी की ओर ले जाएगा। – Ruslan

10

आप मिटा के दो पैरामीटर प्रपत्र का उपयोग किया जाना चाहिए: यदि आप बयान अलग

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest), 
       myVector.end()); 
+0

महान जवाब से मिटा ठीक करने के लिए। धन्यवाद! – MCP

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