std::partition_copy
#include <algorithm>
template <class InputIterator, class OutputIterator1,
class OutputIterator2, class UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2>
partition_copy (InputIterator first, InputIterator last,
OutputIterator1 result_true, OutputIterator2 result_false,
UnaryPredicate pred);
Sao chép các phần tử từ một phạm vi (range) nguồn thành hai phạm vi đích khác nhau, dựa trên kết quả của một hàm vị từ (predicate). Các phần tử thỏa mãn điều kiện sẽ được sao chép vào phạm vi đích thứ nhất, các phần tử không thỏa mãn sẽ được sao chép vào phạm vi đích thứ hai.
Tham số
first
- Input Iterator trỏ đến phần tử đầu tiên trong phạm vi nguồn cần sao chép và phân hoạch.
last
- Input Iterator trỏ đến phần tử ngay sau phần tử cuối cùng trong phạm vi nguồn. Phạm vi nguồn là
[first, last)
.
result_true
- Output Iterator trỏ đến phần tử đầu tiên trong phạm vi đích thứ nhất, nơi các phần tử thỏa mãn điều kiện (hàm vị từ trả về true) sẽ được sao chép đến.
result_false
- Output Iterator trỏ đến phần tử đầu tiên trong phạm vi đích thứ hai, nơi các phần tử không thỏa mãn điều kiện (hàm vị từ trả về false) sẽ được sao chép đến.
pred
- Một hàm vị từ (unary predicate) nhận một đối số là phần tử trong phạm vi nguồn và trả về true nếu phần tử thỏa mãn điều kiện để được sao chép vào
result_true
, false nếu phần tử sẽ được sao chép vàoresult_false
.
Giá trị trả về
- Một std::pair chứa hai Output Iterator:
- pair.first: Iterator trỏ đến phần tử ngay sau phần tử cuối cùng được sao chép vào phạm vi đích thứ nhất (
result_true
). - pair.second: Iterator trỏ đến phần tử ngay sau phần tử cuối cùng được sao chép vào phạm vi đích thứ hai (
result_false
).
- pair.first: Iterator trỏ đến phần tử ngay sau phần tử cuối cùng được sao chép vào phạm vi đích thứ nhất (
Đặc điểm
- Phạm vi nguồn
[first, last)
là "nửa mở", không bao gồm phần tửlast
. - Các phạm vi đích (
result_true
,result_false
) phải có đủ không gian để chứa các phần tử được sao chép. Sử dụng std::back_inserter là một cách an toàn khi sao chép vào container có thể thay đổi kích thước như std::vector. partition_copy()
không thay đổi phạm vi nguồn.partition_copy()
trả về một cặp iterator, lần lượt trỏ đến sau phần tử cuối cùng được sao chép trong mỗi phạm vi đích.partition_copy()
yêu cầu Input Iterator cho phạm vi nguồn và Output Iterator cho các phạm vi đích.- Thứ tự tương đối của các phần tử trong mỗi nhóm đầu ra được giữ nguyên như trong phạm vi nguồn.
- Trong C++11 trở lên, bạn có thể sử dụng biểu thức lambda cho hàm vị từ
pred
để code ngắn gọn và dễ đọc hơn. partition_copy()
thường được sử dụng để:- Tách dữ liệu từ một container thành hai container khác nhau dựa trên một tiêu chí nhất định.
- Sao chép và phân loại dữ liệu từ một nguồn sang hai đích khác nhau mà không làm thay đổi dữ liệu nguồn.
- Kết hợp việc sao chép và phân hoạch dữ liệu trong một bước duy nhất.
Phân biệt với partition(), stable_partition(), và copy_if()
partition()
vàstable_partition()
phân hoạch tại chỗ các phần tử trong phạm vi gốc thành hai nhóm.copy_if()
chỉ sao chép các phần tử thỏa mãn điều kiện sang một phạm vi đích.partition_copy()
sao chép các phần tử vào hai phạm vi đích khác nhau dựa trên việc thỏa mãn hay không thỏa mãn điều kiện.
Ví dụ
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
// Hàm vị từ kiểm tra số chẵn
bool isEven(int n) {
return n % 2 == 0;
}
int main() {
std::vector<int> source = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> evenNumbers;
std::vector<int> oddNumbers;
// Sao chép và phân hoạch source thành evenNumbers và oddNumbers
auto result = std::partition_copy(source.begin(), source.end(),
std::back_inserter(evenNumbers),
std::back_inserter(oddNumbers),
isEven);
std::cout << "evenNumbers: ";
for (int x : evenNumbers) {
std::cout << x << " ";
}
std::cout << std::endl;
std::cout << "oddNumbers: ";
for (int x : oddNumbers) {
std::cout << x << " ";
}
std::cout << std::endl;
// Kiểm tra kết quả của result
std::cout << "Last even number copied to position: " << (result.first - std::begin(evenNumbers)) << std::endl;
std::cout << "Last odd number copied to position: " << (result.second - std::begin(oddNumbers)) << std::endl;
return 0;
}
Các hàm liên quan
is_partitioned | Kiểm tra xem một phạm vi có được phân hoạch theo một điều kiện cho trước hay không |
partition | Sắp xếp lại các phần tử trong một phạm vi |
stable_partition | Phân hoạch các phần tử trong một phạm vi |
partition_point | Tìm vị trí "điểm phân hoạch" đầu tiên trong một phạm vi đã được phân hoạch |