std::list::unique
#include <list>
// Phiên bản 1: Sử dụng toán tử == để so sánh
void unique();
// Phiên bản 2: Sử dụng binary predicate để so sánh
template <class BinaryPredicate>
void unique(BinaryPredicate p);
Xóa các phần tử trùng lặp liên tiếp khỏi std::list.
Tham số
p
-
Một binary predicate xác định cách so sánh hai phần tử. Đây có thể là:
- Một con trỏ hàm.
- Một functor (một đối tượng lớp có
operator()
được nạp chồng). - Một biểu thức lambda.
ghi chúp
phải nhận hai đối số có kiểu làvalue_type
của std::list (hoặc kiểu có thể chuyển đổi thànhvalue_type
) và trả về true nếu hai phần tử được coi là bằng nhau, false nếu ngược lại.
Giá trị trả về
Không có giá trị trả về
Đặc điểm
- Chỉ xóa các phần tử trùng lặp liên tiếp:
unique()
chỉ xóa các phần tử trùng lặp đứng liền kề nhau. Nếu các phần tử trùng lặp không đứng cạnh nhau, chúng sẽ không bị xóa. - Sắp xếp trước khi gọi
unique()
(nếu cần): Để xóa tất cả các phần tử trùng lặp, bạn cần sắp xếp std::list trước khi gọiunique()
. - Hai phiên bản: Phiên bản thứ hai của
unique()
cho phép bạn định nghĩa cách so sánh các phần tử thông qua binary predicate, hữu ích khi bạn muốn so sánh các phần tử dựa trên một tiêu chí cụ thể khác ngoài toán tử==
. - Không làm thay đổi vị trí tương đối của các phần tử còn lại:
unique()
chỉ xóa các phần tử trùng lặp liên tiếp, thứ tự tương đối của các phần tử còn lại được giữ nguyên. - 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.
- Giữ lại phần tử đầu tiên: Trong một chuỗi các phần tử trùng lặp liên tiếp,
unique()
sẽ giữ lại phần tử đầu tiên và xóa các phần tử phía sau. - Không làm thay đổi kích thước tối đa: unique không làm thay đổi giá trị trả về bởi
max_size()
. - Độ phức tạp: Độ phức tạp của
unique()
làO(n)
, với n là số phần tử trong std::list.
Ví dụ
#include <iostream>
#include <list>
// Binary predicate so sánh hai số nguyên (bỏ qua phần lẻ)
bool compare_as_ints(double first, double second) {
return (int)first == (int)second;
}
int main() {
std::list<int> list1 = {1, 2, 2, 2, 3, 3, 2, 1, 1};
list1.unique(); // Xóa các phần tử trùng lặp liên tiếp
std::cout << "list1 after unique():";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after unique(): 1 2 3 2 1
std::cout << '\n';
std::list<double> list2 = {1.1, 2.2, 2.8, 2.3, 3.1, 3.9, 2.5, 1.7, 1.8};
list2.unique(compare_as_ints); // Xóa các phần tử trùng lặp liên tiếp (bỏ qua phần lẻ)
std::cout << "list2 after unique(compare_as_ints):";
for (double x : list2) std::cout << ' ' << x; // Output: list2 after unique(compare_as_ints): 1.1 2.2 3.1 2.5 1.7
std::cout << '\n';
return 0;
}
Sắp xếp trước khi gọi unique()
#include <iostream>
#include <list>
#include <algorithm>
int main() {
std::list<int> mylist = {3, 1, 2, 2, 1, 4, 3, 3, 5};
mylist.sort(); // Sắp xếp danh sách
mylist.unique(); // Xóa các phần tử trùng lặp (bây giờ đã liên tiếp)
std::cout << "mylist after sort() and unique():";
for (int x : mylist) std::cout << ' ' << x; // Output: mylist after sort() and unique(): 1 2 3 4 5
std::cout << '\n';
return 0;
}
Các hàm liên quan
remove | Xó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 |
remove_if | 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 |
erase | Xó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 |
pop_back | Xóa phần tử cuối cùng của std::list |
pop_front | Xóa phần tử đầu tiên của std::list |