2012-01-29 61 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