станд. использования:: заливка для заполнения вектора с растущими числами

Я хотел бы заполнить 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
62
задан 17 July 2013 в 12:20

12 ответов

Предпочтительно используйте 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.
96
ответ дан 31 October 2019 в 13:25

Необходимо использовать 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

34
ответ дан 31 October 2019 в 13:25

Мой предпочтительный вариант (даже в 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, или как что-то, что можно включить рукописный итератор подсчета.)

11
ответ дан 31 October 2019 в 13:25

Если Вы не использовали бы 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.

6
ответ дан 31 October 2019 в 13:25

Я видел ответы со станд.:: генерируйте, но можно также "улучшить" это при помощи статических переменных в лямбде, вместо того, чтобы объявить счетчик за пределами функции или создать класс генератора:

std::vector<int> vec;
std::generate(vec.begin(), vec.end(), [] {
    static int i = 0;
    return i++;
});

я нахожу это немного более кратким

6
ответ дан 31 October 2019 в 13:25

Мы можем использовать , генерируют функция, которая существует в заголовочном файле алгоритма.

Фрагмент кода:

#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;
}
5
ответ дан 31 October 2019 в 13:25

станд.:: йота ограничена последовательностью 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);

, Но я не рекомендовал бы это. :)

4
ответ дан 31 October 2019 в 13:25

это также работает

j=0;
for(std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it){
    *it = j++;
}
2
ответ дан 31 October 2019 в 13:25

Если Вы действительно хотите использовать 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;
}
1
ответ дан 31 October 2019 в 13:25

Разговор о повышении:

auto ivec = boost::copy_range<std::vector<int>>(boost::irange(5, 10));
1
ответ дан 31 October 2019 в 13:25

Я знаю, что это - старый вопрос, но я в настоящее время играю с библиотека для обработки точно этой проблемы. Это требует 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, ...
1
ответ дан 31 October 2019 в 13:25

Я создал простую шаблонную функцию, 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

0
ответ дан 31 October 2019 в 13:25

Другие вопросы по тегам:

Похожие вопросы: