2012-01-29 36 views
12

Tôi đã tạo một hàm để chạy qua một chuỗi các chuỗi và xóa bất kỳ chuỗi nào có độ dài 3 trở xuống. Đây là bài học sử dụng thư viện thuật toán STL.xóa() sau khi thực hiện remove_if()

Tôi đang gặp sự cố khi chức năng hoạt động nhưng không chỉ xóa chuỗi có độ dài từ 3 trở xuống mà còn gắn chuỗi "vectơ" vào cuối.

Sản lượng nên

This test vector 

và thay vào đó là

This test vector vector" 

Làm thế nào tôi có thể sửa chữa nó?

/* 
* 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; 
} 

Trả lời

23

Nó là đơn giản nhất để hiểu được điều này nếu bạn tách các báo cáo:

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

Những 2 dây chuyền làm tương tự như một dòng duy nhất của bạn. Và nó phải rõ ràng bây giờ những gì "lỗi" là. remove_if, hoạt động trước. Nó lặp lại trên toàn bộ vectơ và di chuyển tất cả các mục "đã chọn" tới cuối "(tốt hơn đã nói: nó di chuyển các mục không được chọn lên phía trước). Sau khi nó đã chạy nó trả về một iterator sang vị trí "cuối cùng" của trái qua mục, một cái gì đó như:

này
kiểm tra
vector
kiểm tra < - iterator điểm ở đây
vector

Sau đó, bạn chạy xóa bằng một trình lặp đơn. Điều đó có nghĩa là bạn xóa một phần tử đơn được chỉ ra - vì vậy bạn xóa phần tử "test". - Những gì còn lại là những gì bạn đang nhìn thấy.

Để khắc phục nó chỉ đơn giản là xóa từ vector được trả về bởi remove_if đến cùng() .:

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

Chi tiết tuyệt vời. Cảm ơn bạn rất nhiều vì đã làm rõ những gì đang diễn ra! – MCP

+2

Điều này sẽ cắn nhiều hơn nếu 'myVector' trống. Sau đó 'iter' sẽ bằng' myVector.end() ', và việc xóa bằng cách sử dụng' erase (iter) 'sẽ dẫn đến UB. – Ruslan

10

Bạn nên sử dụng các hình thức hai tham số của erase:

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

Great câu trả lời. Cảm ơn! – MCP

Các vấn đề liên quan