Chuyển tới nội dung chính

std::generate

#include <algorithm>

template <class ForwardIterator, class Generator>
void generate (ForwardIterator first, ForwardIterator last, Generator gen);

Gán các giá trị được sinh ra bởi một hàm (hoặc đối tượng hàm) cho các phần tử trong một phạm vi (range) được chỉ định.

Tham số

first

  • Forward Iterator trỏ đến phần tử đầu tiên trong phạm vi cần gán giá trị.

last

  • Forward Iterator trỏ đến phần tử ngay sau phần tử cuối cùng trong phạm vi cần gán giá trị. Phạm vi là [first, last).

gen

  • Một hàm hoặc đối tượng hàm (generator) không nhận đối số và trả về giá trị để gán cho các phần tử trong phạm vi.

Giá trị trả về

Không có giá trị trả về

Đặc điểm

  1. Phạm vi [first, last) là "nửa mở", không bao gồm phần tử last.
  2. generate() ghi đè giá trị hiện tại của các phần tử trong phạm vi.
  3. generate() yêu cầu Forward Iterator, cho phép di chuyển một chiều về phía trước.
  4. Hàm hoặc đối tượng hàm gen không nhận đối số và phải trả về giá trị có kiểu tương thích để gán được cho kiểu phần tử trong container.
  5. Trong C++11 trở lên, sử dụng biểu thức lambda cho gen thường ngắn gọn và dễ đọc hơn.
  6. Để tạo dãy số tăng dần, std::iota (từ C++11) là một lựa chọn chuyên dụng và thường hiệu quả hơn.
  7. generate() thường được sử dụng để:
    • Khởi tạo một container với các giá trị được sinh ra theo một quy luật nào đó (ví dụ: số ngẫu nhiên, dãy số Fibonacci, giá trị tăng dần).
    • Thay đổi giá trị của các phần tử trong một container dựa trên một hàm sinh giá trị.

Ví dụ

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib> // For rand()
#include <numeric> // For std::iota

// Hàm sinh số ngẫu nhiên
int randomNumber() {
return std::rand() % 100; // Trả về số ngẫu nhiên từ 0 đến 99
}

// Đối tượng hàm sinh dãy số Fibonacci
class FibonacciGenerator {
public:
FibonacciGenerator() : a(0), b(1) {}
int operator()() {
int next = a + b;
a = b;
b = next;
return a;
}
private:
int a;
int b;
};

int main() {
std::vector<int> numbers(10);

// Gán 10 số ngẫu nhiên cho numbers
std::generate(numbers.begin(), numbers.end(), randomNumber);

std::cout << "numbers (random): ";
for (int x : numbers) {
std::cout << x << " ";
}
std::cout << std::endl;

// Gán 10 số Fibonacci đầu tiên cho numbers
FibonacciGenerator fibGen;
std::generate(numbers.begin(), numbers.end(), fibGen);

std::cout << "numbers (Fibonacci): ";
for (int x : numbers) {
std::cout << x << " ";
}
std::cout << std::endl;

// Sử dụng lambda để gán các số chẵn tăng dần
int even = 0;
std::generate(numbers.begin(), numbers.end(), [&even]() { even += 2; return even; });

std::cout << "numbers (even): ";
for (int x : numbers) {
std::cout << x << " ";
}
std::cout << std::endl;

// Gán các số từ 1 đến 10
std::generate(numbers.begin(), numbers.end(), [n = 0] () mutable { return ++n; });
std::cout << "numbers (sequential): ";
for (int x : numbers) {
std::cout << x << " ";
}
std::cout << std::endl;

// Tạo một vector chứa các số từ 1 đến 10
std::vector<int> sequentialNumbers(10);
std::iota(sequentialNumbers.begin(), sequentialNumbers.end(), 1);

std::cout << "sequentialNumbers (using iota): ";
for (int x : sequentialNumbers) {
std::cout << x << " ";
}
std::cout << std::endl;

return 0;
}

Các hàm liên quan

generate_nGán các giá trị được sinh ra bởi một hàm (hoặc đối tượng hàm) cho n phần tử liên tiếp, bắt đầu từ một vị trí được chỉ định
fillGán một giá trị cho tất cả các phần tử trong một phạm vi (range) được chỉ định
for_eachÁ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 được chỉ định