cuốn sách gpt4 ai đã làm

[Hướng dẫn giới thiệu cơ bản về C++ STL] Giải thích chi tiết cách sử dụng hàm biến đổi C++ (STL Transform)

In lại Tác giả: Q123 Thời gian cập nhật: 2024-01-05 20:18:30 29 4
mua khóa gpt4 Nike

Transform() có thể áp dụng một hàm cho các phần tử của một chuỗi và lưu giá trị được hàm này trả về vào một chuỗi khác. Trình vòng lặp nó trả về các điểm đến vị trí bên cạnh phần tử cuối cùng được lưu trong chuỗi đầu ra.

Có một phiên bản của thuật toán này tương tự như for_each() áp dụng hàm đơn nguyên cho một chuỗi các phần tử để thay đổi giá trị của chúng, nhưng có một sự khác biệt lớn. Kiểu trả về của hàm được sử dụng trong for_each() phải là void và giá trị trong chuỗi đầu vào có thể được sửa đổi thông qua tham số tham chiếu của hàm này trong khi hàm nhị phân của Transform() phải trả về một giá trị và cũng có thể là giá trị đó; được sử dụng sau khi áp dụng chức năng. Kết quả thu được sẽ được lưu vào một chuỗi khác.

Không chỉ vậy, các loại phần tử trong chuỗi đầu ra có thể khác với các loại phần tử trong chuỗi đầu vào. Với for_each(), hàm sẽ luôn được áp dụng cho các phần tử của chuỗi, nhưng với Transform(), điều này không được đảm bảo.

Phiên bản thứ hai của Transform() cho phép bạn áp dụng các hàm nhị phân cho các phần tử tương ứng của hai chuỗi, nhưng trước tiên hãy xem cách áp dụng các hàm đơn nhất cho các chuỗi. Trong phiên bản thuật toán này, hai tham số đầu tiên của nó là các trình lặp đầu vào xác định chuỗi đầu vào, tham số thứ ba là trình lặp đầu ra cho phần tử đầu tiên tại đích và tham số thứ tư là hàm nhị phân. Hàm này phải chấp nhận một phần tử từ chuỗi đầu vào làm đối số và phải trả về một giá trị có thể được lưu trong chuỗi đầu ra. Ví dụ:

std::vector deg_C {21.0, 30.5, 0.0, 3.2, 100.0}; std::vector deg_F(deg_C.size()); ::end(deg_C), std:rbegin(deg_F),[](double temp){ return 32.0 + 9.0*temp/5.0 });
Thuật toán Transform() sẽ chuyển đổi nhiệt độ độ C trong vùng chứa deg_C thành Fahrenheit và lưu kết quả vào vùng chứa deg_F. Để lưu tất cả kết quả, deg_F được tạo yêu cầu một số phần tử nhất định. Do đó, tham số thứ ba là trình vòng lặp bắt đầu của deg_F. Bằng cách sử dụng back_insert_iterator làm đối số thứ ba cho Transform(), bạn có thể lưu kết quả vào vùng chứa trống:
std::vector deg_F; // Vùng chứa trống std::transform(std::begin(deg_C), std::end(deg_C),std::back_inserter(deg_F),[](double temp){ return 32,0 + 9,0* tạm thời/5,0 }); // Kết quả 69,8 86,9 32 37,76 212
Sử dụng back_insert_iterator để tạo một phần tử trong deg_F chứa kết quả của phép toán; Tham số thứ ba có thể là một trình vòng lặp trỏ đến các phần tử của vùng chứa đầu vào. Ví dụ:
std::vector nhiệt độ {21.0, 30.5, 0.0, 3.2, 100.0}; // Ở độ C std::transform(std::begin (temps), std::end(temps), std::begin( nhiệt độ),[](nhiệt độ gấp đôi){ trả về 32,0 + 9,0* nhiệt độ / 5,0; }); // Kết quả 69,8 86,9 32 37,76 212
Điều này chuyển đổi giá trị trong vùng chứa nhiệt độ từ độ C sang độ F. Tham số thứ ba là trình vòng lặp bắt đầu của chuỗi đầu vào. Kết quả của việc áp dụng hàm được chỉ định bởi tham số thứ tư sẽ được lưu trở lại phần tử mà nó được áp dụng.

Đoạn mã sau đây cho thấy tình huống trong đó chuỗi đích và chuỗi đầu vào có các loại khác nhau:
std::vector từ {"một", "hai", "ba", "bốn","năm"}; std::vector hash_values; ), std::end(words),std::back_inserter(hash_values),std::hash()); // hàm băm chuỗi std::copy(std::begin(hash_values), std::end(hash_values),std::ostream_iterator {std::cout," "}); std::cout << std::endl;
Chuỗi đầu vào chứa các đối tượng chuỗi và hàm được áp dụng cho các phần tử là đối tượng hàm băm tiêu chuẩn được xác định trong tệp tiêu đề chuỗi. Hàm băm này sẽ trả về các giá trị băm thuộc loại size_t và sẽ lưu các giá trị này vào vùng chứa hash_values ​​bằng cách sử dụng back_insert_iterator được trả về bởi hàm phụ trợ back_inserter() được xác định trong tệp tiêu đề iterator. Trên hệ thống của tôi, mã này tạo ra kết quả đầu ra sau:

3123124719 3190065193 2290484163 795473317 2931049365

Hệ thống của bạn có thể tạo ra đầu ra khác nhau. Lưu ý rằng vì trình tự đích được chỉ định bởi đối tượng back_insert_iterator nên thuật toán Transform() ở đây sẽ trả về một trình vòng lặp kiểu back_insert_iterator<>>, do đó nó không thể được sử dụng làm trình vòng lặp cuối của chuỗi đầu vào trong bản sao( ) thuật toán. Để tận dụng tối đa trình lặp được trả về bởi Transform(), mã này có thể được viết như sau:
std::vector từ {"một", "hai", "ba", "bốn", "năm"}; std::vector hash_values(words.size()); ::transform(std::begin(words),std::end(words), std::begin(hash_values), std::hash()); // hàm băm chuỗi std::copy(std::begin(hash_values) , end_iter, std::ostream iterator{std::cout," "}) ; std::cout << std::endl;
Bây giờ, Transform() trả về trình vòng lặp cuối cùng của chuỗi các phần tử trong vùng chứa hash_values.

Một thuật toán có thể được gọi cho một chuỗi các phần tử trong hàm được sử dụng bởi Transform(). Dưới đây là một số ví dụ:
std::deque tên {"Srám nắng Laurel", "Oliver Hardy", "Harold Lloyd"}; std::transform(std::begin(names), std::end(names), std::begin(names),[](string& s) { std::transform(std::begin(s), std::end(s), std::begin(s), ::người cao hơn);return s;}); std::copy(std::begin(names), std::end(names), std::ostream iterator{std::cout," "}); :cout << std::endl;
Thuật toán Transform() áp dụng hàm được xác định bởi lambda cho các phần tử trong vùng chứa tên. Biểu thức lambda này gọi Transform(), áp dụng hàm toupper() được xác định trong tệp tiêu đề cctype cho từng ký tự của chuỗi được truyền tới nó. Nó chuyển đổi từng phần tử trong tên thành chữ hoa, do đó kết quả đầu ra là:

STAN LAUREL OLIVER HARDY HAROLD LLOYD

Tất nhiên, có nhiều cách khác đơn giản hơn để có được kết quả tương tự.

Phiên bản Transform() áp dụng hàm nhị phân này có 5 đối số:
  • Hai tham số đầu tiên là các biến lặp đầu vào cho chuỗi đầu vào đầu tiên.
  • Tham số thứ ba là trình lặp bắt đầu của chuỗi đầu vào thứ hai Rõ ràng, chuỗi này phải chứa ít nhất nhiều phần tử như chuỗi đầu vào đầu tiên.
  • Tham số thứ tư là trình vòng lặp đầu ra của một chuỗi, nó trỏ đến trình vòng lặp bắt đầu của chuỗi được sử dụng để lưu kết quả thu được sau khi áp dụng hàm.
  • Tham số thứ năm là một đối tượng hàm, xác định một hàm chấp nhận hai tham số. Hàm này chấp nhận các phần tử từ hai chuỗi đầu vào làm tham số và trả về một giá trị có thể được lưu trong chuỗi đầu ra.

Hãy xem xét một ví dụ đơn giản về tính toán hình học. Một polyline bao gồm các đường liên tục giữa các điểm. Một đa tuyến có thể được biểu diễn dưới dạng vectơ của các đối tượng Điểm và đoạn đa tuyến là một đường nối các điểm liên tiếp. Nếu điểm cuối cùng giống với điểm trước đó thì đường đa tuyến đó là một đa giác khép kín.

Hình 1 Một đường đa tuyến biểu thị một hình lục giác

Điểm được định nghĩa là bí danh loại, Hình 1 hiển thị một ví dụ:
bạntội lỗig Point = std::pair; // pair xác định một điểm
Có 7 điểm ở đây, vậy vật thể lục giác trong Hình 1 có 6 đoạn đa tuyến. Vì điểm đầu và điểm cuối giống nhau nên 6 đoạn thẳng này thực chất tạo thành một đa giác - hình lục giác. Độ dài của các đoạn này có thể được tính bằng thuật toán Transform():
std::vector lục giác {{1,2}, {2,1}, {3,1}, {4,2}, {3,3}, {2,3}, {1,2} }; std::vector đoạn; // Lưu trữ độ dài của đoạn std::transform (std::begin (hexagon),std::end(hexagon) — 1, std::begin (hình lục giác) + 1, std::back_inserter(phân đoạn),[](const Điểm p1, const Điểm p2){return st d::sqrt((p1.first-p2.first)*(p1.first-p2. đầu tiên) +(p1.second - p2.second)*(p1.second - p2.second) });
Chuỗi đầu vào đầu tiên của Transform() chứa các đối tượng Point từ đầu đến cuối trong hình lục giác. Chuỗi đầu vào thứ hai bắt đầu với đối tượng Point thứ hai, do đó, các đối số liên tiếp cho lệnh gọi hàm nhị phân này là điểm 1 và 2, điểm 2 và 3, điểm 3 và 4, v.v. cho đến hai điểm cuối cùng của chuỗi đầu vào. 6 và 7. Hình 1 thể hiện công thức tính khoảng cách giữa hai điểm (x1, y1) và (x2, y2). Biểu thức lambda là tham số cuối cùng của Transform() thực hiện công thức này. Độ dài của các đoạn đường được tính bằng biểu thức lambda và chúng được lưu trữ trong vùng chứa đoạn. Chúng ta có thể sử dụng nhiều hơn hai thuật toán để xuất ra độ dài của đoạn thẳng và chu vi của hình lục giác. Ví dụ:
std::cout << "Độ dài đoạn: "; std::copy(std::begin(segments), std::end(segments),std::ostream_iterator {std::cout," "}) ; std::cout << std::endl; std::cout << "Chu vi hình lục giác: "<< std::accumulate(std::begin(segments), std::end(segments), 0.0) << std::endl;
Thuật toán copy() được sử dụng ở đây để xuất ra độ dài của đoạn đường. Hàm tích lũy () có thể tính tổng các giá trị phần tử trong các phân đoạn để thu được chu vi.
29 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress