std::replace_copy_if
#include <algorithm>
template <class InputIterator, class OutputIterator, class UnaryPredicate, class T>
OutputIterator replace_copy_if (InputIterator first, InputIterator last,
OutputIterator result,
UnaryPredicate pred, const T& new_value);
Sao chép các phần tử từ một phạm vi (range) nguồn sang một phạm vi đích khác, đồng thời thay thế các phần tử thỏa mãn một điều kiện cụ thể (được xác định bởi một hàm vị từ) bằng một giá trị mới trong quá trình sao chép.
Tham số
first
- Input Iterator trỏ đến phần tử đầu tiên trong phạm vi nguồn cần sao chép.
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
- Output Iterator trỏ đến phần tử đầu tiên trong phạm vi đích nơi các phần tử 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 để bị thay thế trong quá trình sao chép, false nếu không.
new_value
- Giá trị mới sẽ thay thế cho các phần tử thỏa mãn điều kiện.
Giá trị trả về
- Output Iterator trỏ đến phần tử ngay sau phần tử cuối cùng được sao chép trong phạm vi đích.
Đặc điểm
- Phạm vi nguồn
[first, last)
là "nửa mở", không bao gồm phần tửlast
. - Phạm vi đích 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.
replace_copy_if()
không thay đổi phạm vi nguồn.replace_copy_if()
trả về iterator trỏ đến sau phần tử cuối cùng được sao chép trong phạm vi đích.- Trong C++11 trở lên, sử dụng biểu thức lambda cho hàm vị từ pred thường ngắn gọn và dễ đọc hơn.
replace_copy_if()
thường được sử dụng để:- Tạo một bản sao của một container, đồng thời thay thế các phần tử thỏa mãn một tiêu chí nhất định bằng một giá trị mới.
- Sao chép và lọc dữ liệu từ một nguồn sang một đích khác, thay thế các giá trị không mong muốn.
- Kết hợp việc sao chép, lọc và thay thế trong một bước duy nhất.
Phân biệt với replace_if(), replace_copy(), và copy_if()
replace_if()
thay thế trực tiếp các giá trị trong phạm vi nguồn dựa trên một điều kiện.replace_copy()
sao chép và thay thế các giá trị bằng nhau trong phạm vi đích.copy_if()
chỉ sao chép các phần tử thỏa mãn điều kiện sang phạm vi đích.replace_copy_if()
kết hợp cả ba: sao chép, lọc (dựa trên điều kiện) và thay thế vào một phạm vi mới.
Ví dụ
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
// Hàm vị từ kiểm tra số lẻ
bool isOdd(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> destination;
// Sao chép source sang destination, thay thế số lẻ bằng 0
std::replace_copy_if(source.begin(), source.end(), std::back_inserter(destination), isOdd, 0);
std::cout << "destination after replace_copy_if: ";
for (int x : destination) {
std::cout << x << " ";
}
std::cout << std::endl;
std::string str = "apple banana orange kiwi";
std::string resultStr;
// Sao chép str sang resultStr, thay thế các nguyên âm bằng '_' sử dụng lambda
std::replace_copy_if(str.begin(), str.end(), std::back_inserter(resultStr),
[](char c){ return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; },
'_');
std::cout << "resultStr after replace_copy_if: " << resultStr << std::endl;
return 0;
}
Các hàm liên quan
remove_copy_if | Sao chép các phần tử từ một phạm vi (range) nguồn sang một phạm vi đích khác |
replace | Thay thế tất cả các lần xuất hiện của một giá trị cũ bằng một giá trị mới trong một phạm vi (range) |
replace_copy | Sao chép các phần tử từ một phạm vi (range) nguồn sang một phạm vi đích khác |
transform | Áp dụng một hàm (hoặc đối tượng hàm) cho mỗi phần tử trong một phạm vi (range) đầu vào và lưu trữ kết quả vào một phạm vi đầu ra |