Nhân bản vector
Không giống R, C++ sử dụng hệ thống sao chép theo tham chiếu (copy by reference), nghĩa là nếu bạn sao chép một biến rồi thay đổi bản sao, các thay đổi đó cũng sẽ xảy ra trên bản gốc.
// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
// Tạo một bản sao
NumericVector y = x;
// Sửa đổi bản sao
y[0] = 2;
// Các thay đổi cũng xảy ra ở bản gốc
return x[0];
}
Để tránh hành vi này, bạn cần dùng hàm clone() để sao chép dữ liệu nền từ biến gốc sang biến mới. Cú pháp là y = clone(x).
Trong bài này, chúng tôi đã định nghĩa sẵn cho bạn hai hàm:
change_negatives_to_zero(): Nhận một numeric vector, sửa bằng cách thay các số âm thành 0, rồi trả về cả vector gốc và bản sao.change_negatives_to_zero_with_cloning(): Làm giống như trên, nhưng nhân bản (clone) vector gốc trước khi sửa.
Bài tập này là một phần của khóa học
Tối ưu hóa mã R với Rcpp
Hướng dẫn bài tập
- Hoàn thiện định nghĩa hàm
change_negatives_to_zero()bằng cách gánthe_originalchothe_copy. - Hoàn thiện định nghĩa hàm
change_negatives_to_zero_with_cloning()bằng cách gánthe_copybằng bản clone củathe_original. - Đọc nội dung trên console để so sánh đầu ra của từng hàm.
Bài tập tương tác thực hành trực tiếp
Hãy thử làm bài tập này bằng cách hoàn thành đoạn mã mẫu này.
#include
using namespace Rcpp;
// [[Rcpp::export]]
List change_negatives_to_zero(NumericVector the_original) {
// Set the copy to the original
NumericVector the_copy = ___;
int n = the_original.size();
for(int i = 0; i < n; i++) {
if(the_copy[i] < 0) the_copy[i] = 0;
}
return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}
// [[Rcpp::export]]
List change_negatives_to_zero_with_cloning(NumericVector the_original) {
// Clone the original to make the copy
NumericVector the_copy = ___;
int n = the_original.size();
for(int i = 0; i < n; i++) {
if(the_copy[i] < 0) the_copy[i] = 0;
}
return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}
/*** R
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero(x)
# Need to define x again because it's changed now
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero_with_cloning(x)
*/