Я хотел бы заполнить a vector<int>
использование std::fill
, но вместо одного значения, вектор должен содержать числа в увеличивающемся порядке после.
Я пытался достигнуть этого путем итерации третьего параметра функции одной, но это только даст мне или векторы, заполненные 1 или 2 (в зависимости от положения ++
оператор).
Пример:
vector<int> ivec;
int i = 0;
std::fill(ivec.begin(), ivec.end(), i++); // elements are set to 1
std::fill(ivec.begin(), ivec.end(), ++i); // elements are set to 2
Предпочтительно используйте std::iota
как это:
std::vector<int> v(100) ; // vector with 100 ints.
std::iota (std::begin(v), std::end(v), 0); // Fill with 0, 1, ..., 99.
Тем не менее, если у Вас нет никакого c++11
поддержка (все еще настоящая проблема, где я работаю), используйте std::generate
как это:
struct IncGenerator {
int current_;
IncGenerator (int start) : current_(start) {}
int operator() () { return current_++; }
};
// ...
std::vector<int> v(100) ; // vector with 100 ints.
IncGenerator g (0);
std::generate( v.begin(), v.end(), g); // Fill with the result of calling g() repeatedly.
Необходимо использовать std::iota
алгоритм:
std::vector<int> ivec;
std::iota(ivec.begin(), ivec.end(), 0);
, поскольку std::fill
просто присваивает данное фиксированное значение элементам в данном диапазоне [n1, n2). И std::iota
заливки данный диапазон [n1, n2) с последовательным увеличиванием значений, начиная с начального значения и затем использования ++value
.You может также использовать std::generate
в качестве альтернативы.
не забывают, что std::iota
C++ 11 алгоритмов STL. Но много современных компиляторов поддерживает его, например, GCC, Лязг и VS2012: http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx
Мой предпочтительный вариант (даже в C++ 11) был бы boost::counting_iterator
:
std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
boost::counting_iterator<int>( n ) );
или если вектор был уже создан:
std::copy( boost::counting_iterator<int>( 0 ),
boost::counting_iterator<int>( ivec.size() ),
ivec.begin() );
, Если Вы не можете использовать Повышение: любой std::generate
(как предложено в других ответах), или реализация counting_iterator
самостоятельно, если Вам нужен он в различных местах. (С Повышением можно использовать transform_iterator
из counting_iterator
для создания всех видов интересных последовательностей. Без Повышения можно сделать многое из этого вручную, или в форме типа объекта генератора для std::generate
, или как что-то, что можно включить рукописный итератор подсчета.)
Если Вы не использовали бы C++ 11 функций, можно использовать std::generate
:
#include <algorithm>
#include <iostream>
#include <vector>
struct Generator {
Generator() : m_value( 0 ) { }
int operator()() { return m_value++; }
int m_value;
};
int main()
{
std::vector<int> ivec( 10 );
std::generate( ivec.begin(), ivec.end(), Generator() );
std::vector<int>::const_iterator it, end = ivec.end();
for ( it = ivec.begin(); it != end; ++it ) {
std::cout << *it << std::endl;
}
}
Эта программа печатает от 0 до 9.
Я видел ответы со станд.:: генерируйте, но можно также "улучшить" это при помощи статических переменных в лямбде, вместо того, чтобы объявить счетчик за пределами функции или создать класс генератора:
std::vector<int> vec;
std::generate(vec.begin(), vec.end(), [] {
static int i = 0;
return i++;
});
я нахожу это немного более кратким
Мы можем использовать , генерируют функция, которая существует в заголовочном файле алгоритма.
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
vector<int>v(10);
int n=0;
generate(v.begin(), v.end(), [&n] { return n++;});
for(auto item : v)
{
cout<<item<<" ";
}
cout<<endl;
return 0;
}
станд.:: йота ограничена последовательностью n, n+1, n+2...
, Но что, если Вы хотите заполнить массив универсальной последовательностью f (0), f (1), f (2), и т.д.? Часто, мы можем избежать генератора отслеживания состояния. Например,
int a[7];
auto f = [](int x) { return x*x; };
transform(a, a+7, a, [a, f](int &x) {return f(&x - a);});
произведет последовательность квадратов
0 1 4 9 16 25 36
Однако, этот прием не будет работать с другими контейнерами.
, Если Вы застреваете с C++ 98, можно сделать ужасные вещи как:
int f(int &x) { int y = (int) (long) &x / sizeof(int); return y*y; }
и затем
int a[7];
transform((int *) 0, ((int *) 0) + 7, a, f);
, Но я не рекомендовал бы это. :)
это также работает
j=0;
for(std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it){
*it = j++;
}
Если Вы действительно хотите использовать std::fill
и ограничены C++ 98, можно использовать что-то как следующее,
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
struct increasing {
increasing(int start) : x(start) {}
operator int () const { return x++; }
mutable int x;
};
int main(int argc, char* argv[])
{
using namespace std;
vector<int> v(10);
fill(v.begin(), v.end(), increasing(0));
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Разговор о повышении:
auto ivec = boost::copy_range<std::vector<int>>(boost::irange(5, 10));
Я знаю, что это - старый вопрос, но я в настоящее время играю с библиотека для обработки точно этой проблемы. Это требует C++ 14.
#include "htl.hpp"
htl::Token _;
std::vector<int> vec = _[0, _, 100];
// or
for (auto const e: _[0, _, 100]) { ... }
// supports also custom steps
// _[0, _%3, 100] == 0, 4, 7, 10, ...
Я создал простую шаблонную функцию, Sequence()
, для генерации последовательностей чисел. Функциональность следует эти seq()
функция в R ( ссылка ). Хорошая вещь об этой функции состоит в том, что она работает на генерацию множества последовательностей числа и типов.
#include <iostream>
#include <vector>
template <typename T>
std::vector<T> Sequence(T min, T max, T by) {
size_t n_elements = ((max - min) / by) + 1;
std::vector<T> vec(n_elements);
min -= by;
for (size_t i = 0; i < vec.size(); ++i) {
min += by;
vec[i] = min;
}
return vec;
}
использование В качестве примера:
int main()
{
auto vec = Sequence(0., 10., 0.5);
for(auto &v : vec) {
std::cout << v << std::endl;
}
}
единственный протест состоит в том, что все числа должны иметь тот же выведенный тип. Другими словами, для удваивается или плавает, включайте десятичные числа для всех исходных данных, как показано.
Обновленный: 14 июня 2018