C++
Generate в C++: как заполнить vector и массив
В C++ std::generate — это алгоритм из заголовка <algorithm>. Он проходит по диапазону и записывает в каждый элемент значение, которое возвращает функция-генератор
Короткая схема:
std::generate(begin, end, generator);
Где generator — функция, lambda или объект, который можно вызвать без аргументов
Заполнить vector числами
Пример: заполнить std::vector числами от 1 до 5
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers(5);
int value = 1;
std::generate(numbers.begin(), numbers.end(), [&value]() {
return value++;
});
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Вывод:
1 2 3 4 5
Вектор заранее создан размером 5. std::generate не добавляет новые элементы, а заполняет уже существующие
Заполнить массив
std::generate работает и с обычным массивом:
#include <algorithm>
#include <iostream>
#include <iterator>
int main() {
int numbers[5];
int value = 10;
std::generate(std::begin(numbers), std::end(numbers), [&value]() {
value += 10;
return value;
});
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Результат:
20 30 40 50 60
Заполнить случайными числами
Для случайных чисел лучше использовать <random>, а не старый rand()
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
int main() {
std::vector<int> numbers(10);
std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 100);
std::generate(numbers.begin(), numbers.end(), [&]() {
return dist(engine);
});
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Каждый запуск может дать новый набор чисел
generate и back_inserter
Важный момент: обычный std::generate заполняет существующий диапазон. Если вектор пустой, такой код ничего не сделает:
std::vector<int> numbers;
std::generate(numbers.begin(), numbers.end(), generator);
Если нужно именно добавить элементы, используйте std::generate_n с std::back_inserter:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<int> numbers;
int value = 1;
std::generate_n(std::back_inserter(numbers), 5, [&value]() {
return value++;
});
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Когда использовать std::generate
std::generate удобен, когда значение каждого элемента получается по правилу:
- счетчик;
- случайное число;
- результат функции;
- объект с изменяющимся состоянием;
- тестовые данные для массива или вектора.
Если нужно просто заполнить все элементы одним значением, берите std::fill
generate и fill: в чем разница
std::fill записывает одно и то же значение во все элементы:
std::fill(numbers.begin(), numbers.end(), 10);
std::generate каждый раз вызывает генератор:
std::generate(numbers.begin(), numbers.end(), [&value]() {
return value++;
});
Поэтому fill подходит для одинаковых значений, а generate — для последовательностей, случайных чисел и тестовых данных, где каждый элемент должен вычисляться отдельно
generate не меняет размер контейнера
Если вектор создан так:
std::vector<int> numbers(5);
в нем уже есть пять элементов, и generate их заполнит. Если вектор пустой:
std::vector<int> numbers;
диапазон begin() — end() пустой. Поэтому для добавления новых элементов нужен generate_n и back_inserter
Частые ошибки
Запускать generate по пустому vector
Если begin() == end(), диапазон пустой и алгоритм ничего не заполнит. Создайте размер заранее или используйте generate_n
Думать, что generator принимает индекс
Генератор для std::generate вызывается без аргументов. Если нужен индекс, храните счетчик во внешней переменной
Забыть include
Для std::generate нужен:
#include <algorithm>
Короткий вывод
std::generate в C++ заполняет существующий диапазон значениями из генератора. Для vector заранее задайте размер или используйте std::generate_n с std::back_inserter, если элементы нужно добавлять
Связанные материалы:
Что почитать дальше по C++
Если нужен общий маршрут по теме, откройте рубрику C++. Для соседних задач пригодятся эти разборы:
- Сортировка массива в C++: std::sort, обычный массив и vector
- Как передать массив в функцию C++: размер, vector, array и span
- Массивы в C++: обычный массив, vector и базовые операции
- Enter в C++: перенос строки, std::endl и ввод через cin