2009-03-14 32 views

Trả lời

21

tôi thích remove_if

v.erase(remove_if(v.begin(), v.end(), 
       mem_fun_ref(&MyClass::isTiredOfLife)), 
     v.end()); 

remove_if trả về một iterator trỏ sau khi yếu tố cuối cùng đó là vẫn còn trong chuỗi. erase xóa mọi thứ từ đầu tiên đến đối số cuối cùng của nó (cả hai vòng lặp).

+1

Tôi quên về remove_if() +1 . –

+0

Rất hay. Chưa bao giờ thấy điều đó trước đây. +1 – Bernard

+0

Cảm ơn, điều đó đã xảy ra. –

6

Sử dụng remove_if là cách "đúng" để thực hiện việc này. Cẩn thận KHÔNG sử dụng một trình lặp để chu kỳ và xóa, vì việc loại bỏ các mục làm mất hiệu lực trình lặp. Trong thực tế, bất kỳ ví dụ nào sử dụng phương thức xóa() làm phương thức chính của nó là một ý tưởng tồi trên vectơ, bởi vì xóa là O (n), nó sẽ làm cho thuật toán của bạn O (n^2). Đây phải là một thuật toán O (n).

Phương pháp tôi đưa ra bên dưới có thể nhanh hơn remove_if nhưng không giống như remove_if, sẽ KHÔNG giữ nguyên thứ tự tương đối của các phần tử. Nếu bạn quan tâm đến việc duy trì trật tự (ví dụ: vectơ của bạn được sắp xếp), hãy sử dụng remove_if, như trong câu trả lời ở trên. Nếu bạn không quan tâm đến trật tự và nếu số lượng mục cần xóa thường ít hơn một phần tư của vectơ, thì phương pháp này có thể nhanh hơn:

for(size_t i = 0; i < vec.size();) 
    if(vec[i].isTiredOfLife()) 
    { 
     vec[i] = vec.back(); 
     vec.pop_back(); 
    } 
    else 
     ++i; 
+0

D'oh. Tôi quên mất điều đó. Nó thậm chí còn in đậm trong trang tôi đã liên kết. : o Tôi đã xóa bài đăng của mình, vì vậy không ai sử dụng nó. – Bernard

+0

Sẽ không sắp xếp lại các phần tử trong vectơ? Giả sử rằng, ví dụ, vector đầu vào được sắp xếp, vector đầu ra sẽ không, phần tử cuối cùng sẽ lấy vị trí của phần tử đã xóa đầu tiên. –

+0

Bạn có thể muốn cập nhật câu trả lời của mình để không đề cập đến Bernard nữa. –

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