Chuyển tới nội dung chính

std::list::remove_if

#include <list>

template <class UnaryPredicate>
void remove_if(UnaryPredicate p);

Xóa tất cả các phần tử thỏa mãn một điều kiện cụ thể khỏi std::list. Điều kiện này được xác định bởi một unary predicate (một hàm hoặc functor nhận một đối số và trả về true hoặc false).

Tham số

p

  • Một unary predicate xác định điều kiện xóa phần tử. Đây có thể là:

    • Một con trỏ hàm (như isEven trong ví dụ).
    • Một functor (một đối tượng lớp có operator() được nạp chồng).
    • Một biểu thức lambda (như [](int n) { return n > 5; } trong ví dụ).
    ghi chú

    p phải nhận một đối số có kiểu là value_type của std::list (hoặc kiểu có thể chuyển đổi thành value_type) và trả về true nếu phần tử tương ứng nên bị xóa, false nếu ngược lại.

Giá trị trả về

Không có giá trị trả về

Đặc điểm

  1. Xóa theo điều kiện: remove_if() xóa tất cả các phần tử thỏa mãn điều kiện được xác định bởi p, không phải xóa theo giá trị cụ thể như remove().
  2. Duyệt toàn bộ danh sách: remove_if() phải duyệt qua toàn bộ std::list để kiểm tra từng phần tử.
  3. Không làm thay đổi vị trí tương đối của các phần tử còn lại: remove_if() chỉ xóa các phần tử thỏa mãn điều kiện, thứ tự tương đối của các phần tử còn lại được giữ nguyên.
  4. Có thể làm thay đổi iterator: Thao tác xóa phần tử có thể làm thay đổi (invalidate) các iterator đang trỏ đến std::list.
  5. Phân biệt với remove(): remove() xóa phần tử theo giá trị cụ thể, còn remove_if() xóa phần tử theo điều kiện tổng quát hơn.
  6. Không làm thay đổi kích thước tối đa: remove_if() không làm thay đổi giá trị trả về bởi max_size().
  7. Độ phức tạp: Độ phức tạp của remove_if()O(n), với n là số phần tử trong std::list.

Ví dụ

#include <iostream>
#include <list>

// Hàm kiểm tra số chẵn
bool isEven(int n) {
return n % 2 == 0;
}

int main() {
std::list<int> mylist = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// Xóa tất cả các số chẵn (sử dụng hàm isEven)
mylist.remove_if(isEven);

std::cout << "mylist after remove_if(isEven):";
for (int x : mylist) std::cout << ' ' << x; // Output: mylist after remove_if(isEven): 1 3 5 7 9
std::cout << '\n';

// Xóa tất cả các số lớn hơn 5 (sử dụng lambda function)
mylist.remove_if([](int n) { return n > 5; });

std::cout << "mylist after remove_if(n > 5):";
for (int x : mylist) std::cout << ' ' << x; // Output: mylist after remove_if(n > 5): 1 3 5
std::cout << '\n';

return 0;
}

Sử dụng functor

#include <iostream>
#include <list>
#include <string>

// Functor kiểm tra độ dài chuỗi
class StringLengthChecker {
public:
StringLengthChecker(size_t len) : length(len) {}

bool operator()(const std::string& str) const {
return str.length() > length;
}

private:
size_t length;
};

int main() {
std::list<std::string> mylist = {"apple", "banana", "kiwi", "grapefruit", "pear"};

// Xóa tất cả các chuỗi có độ dài lớn hơn 5
StringLengthChecker checker(5);
mylist.remove_if(checker);

std::cout << "mylist after remove_if(StringLengthChecker(5)):";
for (const std::string& str : mylist) std::cout << ' ' << str; // Output: mylist after remove_if(StringLengthChecker(5)): apple kiwi pear
std::cout << '\n';

return 0;
}

Các hàm liên quan

removeXóa tất cả các phần tử có giá trị bằng với một giá trị cho trước khỏi std::list
eraseXóa một hoặc nhiều phần tử khỏi std::list tại một vị trí cụ thể hoặc trong một phạm vi
uniqueXóa các phần tử trùng lặp liên tiếp khỏi std::list
pop_backXóa phần tử cuối cùng của std::list
pop_frontXóa phần tử đầu tiên của std::list