使用std :: fill来填充向量越来越多的数字

Bla*_*mba 65 c++ stl

我想填充一个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
Run Code Online (Sandbox Code Playgroud)

BoB*_*ish 97

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.
Run Code Online (Sandbox Code Playgroud)

也就是说,如果你没有任何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.
Run Code Online (Sandbox Code Playgroud)

  • 它不会"支持"任何东西,它是希腊语等同于字母i.它是用于[APL中的类似函数]的名称(http://aplwiki.com/LearnApl/BuiltInFunctions#line-176),以及引发Stepanov STL中许多想法的数组语言. (7认同)
  • iota到底代表什么?(好像有人输错了同样清晰的“ itoa”。) (2认同)
  • 啊哈谢谢!好吧,它是一个单词而不是首字母缩写;现在我可能会更幸运地记住这一点。CPP Reference 谈到了“起始值的增量”(注意轻微的相似性),所以我的脑海中浮现出缩写。(谷歌搜索并不能立即明显看出希腊语的联系。)也感谢您的历史参考。 (2认同)

Ole*_*rov 34

你应该使用std::iota算法:

  std::vector<int> ivec;
  std::iota(ivec.begin(), ivec.end(), 0);
Run Code Online (Sandbox Code Playgroud)

因为std::fill只是将给定的固定值分配给给定范围[n1,n2]中的元素.和std::iota填充用依次增大的值,与初始值开始,然后在给定范围[N1,N2) ++value.您还可以使用std::generate作为替代.

不要忘记那std::iota是C++ 11 STL算法.但是很多现代编译器都支持它,例如GCC,Clang和VS2012:http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx

  • 该向量的大小为 0。您需要向容器添加一个大小: std::vector&lt;int&gt; ivec( 100); std::iota(ivec.begin(), ivec.end(), 0); (2认同)

Jam*_*nze 11

我的第一选择(即使在C++ 11中)将是 boost::counting_iterator:

std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
                       boost::counting_iterator<int>( n ) );
Run Code Online (Sandbox Code Playgroud)

或者如果已经构造了向量:

std::copy( boost::counting_iterator<int>( 0 ),
           boost::counting_iterator<int>( ivec.size() ),
           ivec.begin() );
Run Code Online (Sandbox Code Playgroud)

如果你不能使用Boost:或者std::generate(如其他答案中所建议的那样),或者counting_iterator你自己实现,如果你需要在不同的地方.(有增强,你可以使用transform_iteratorcounting_iterator创建各种有趣的序列,没有加速,你可以手工做很多这一点,无论是在一台发电机的对象类型的形式std::generate,或者是你可以插入一个手写计数迭代器.)


小智 7

我已经看到了std :: generate的答案,但是您也可以通过在lambda中使用静态变量来“改善”它,而不是在函数外部声明一个计数器或创建一个generator类:

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

我觉得它更简洁

  • IMO此处的“ static”语义错误。我将使用通用捕获`[i = 0]()mutable`,以便很明显该变量的作用域为lambda的特定实例,而不是其生成的类类型。很难想像实践上会有差异的情况,这可能表明设计存在问题,但是无论如何,我认为使用成员变量的语义是优越的。另外,它使代码更简洁;现在,lambda的主体可以是单个语句。 (4认同)

Fre*_*abe 6

如果您不想使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序打印0到9.

  • @bitmask肯定如果你有lambdas你还有`std :: iota`,不是吗? (3认同)
  • 什么是非直观和非简化的事实是`it`和`end`是在for-loop之外定义的.有什么理由吗? (2认同)
  • @ChristianRau:说实话:在实践中,我使用我正在编辑的文件中的代码使用的任何样式,即我认为一致性高于我们目前提到的优点或缺点. (2认同)

pur*_*uru 6

std::iota 仅限于序列 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);});
Run Code Online (Sandbox Code Playgroud)

将产生正方形序列

0 1 4 9 16 25 36
Run Code Online (Sandbox Code Playgroud)

然而,这个技巧不适用于其他容器。

如果你坚持使用 C++98,你可能会做一些可怕的事情,比如:

int f(int &x) { int y = (int) (long) &x / sizeof(int); return y*y; }
Run Code Online (Sandbox Code Playgroud)

进而

int a[7];
transform((int *) 0, ((int *) 0) + 7, a, f);
Run Code Online (Sandbox Code Playgroud)

但我不会推荐它。:)


ras*_*dcs 5

我们可以使用算法头文件中存在的generate函数。

代码段:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • IMO 通过广义捕获“[n = 0]() mutable”使“n”成为 lambda 的成员更好,因此它不会污染周围的范围。 (2认同)