2012-01-29 71 views
12

我創建了一個函數來運行一個字符串矢量並刪除任何長度爲3或更小的字符串。這是使用STL算法庫的教訓。執行remove_if()後擦除()

我遇到了麻煩的功能工作,但不僅它刪除長度爲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,首先工作。它遍歷整個矢量並將所有「選定」條目「移動到最後」(更好地說:它將未選定的條目移動到前面)。之後,它已經運行它返回一個迭代器的遺留項目的「最後」的位置,這樣的:


測試
矢量
測試< - 迭代器指向這裏
矢量

然後你用一個迭代器運行擦除。這意味着你擦除指向的單個元素 - 以便擦除「test」元素。 - 剩下的就是你所看到的。

要修復它只是從()的返回的remove_if到最終的載體:

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

偉大的細節。非常感謝你澄清發生了什麼! – MCP 2012-01-29 14:50:38

+2

如果'myVector'是空的,這會更糟。然後'iter'將等於'myVector.end()',並且使用'erase(iter)'擦除將導致UB。 – Ruslan 2015-08-07 08:48:48

10

您應該使用擦除的兩個參數的形式:

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

大答案擦除。謝謝! – MCP 2012-01-29 14:49:42