C++ 使用 std::fill 填充带有递增数字的向量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17694579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
use std::fill to populate vector with increasing numbers
提问by BlackMamba
I would like to fill a vector<int>
using std::fill
, but instead of one value, the vector should contain numbers in increasing order after.
我想填充vector<int>
using std::fill
,但不是一个值,向量应包含按递增顺序排列的数字。
I tried achieving this by iterating the third parameter of the function by one, but this would only give me either vectors filled with 1 or 2 (depending of the position of the ++
operator).
我尝试通过将函数的第三个参数迭代 1 来实现这一点,但这只会给我填充 1 或 2 的向量(取决于++
运算符的位置)。
Example:
例子:
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
回答by BoBTFish
Preferably use std::iota
like this:
最好这样使用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.
That said, if you don't have any c++11
support (still a real problem where I work), use std::generate
like this:
也就是说,如果您没有任何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.
回答by Oleksandr Karaberov
You should use std::iota
algorithm (defined in <numeric>
):
您应该使用std::iota
算法(在 中定义<numeric>
):
std::vector<int> ivec(100);
std::iota(ivec.begin(), ivec.end(), 0); // ivec will become: [0..99]
Because std::fill
just assigns the given fixed value to the elements in the given range [n1,n2)
. And std::iota
fills the given range [n1, n2)
with sequentially increasing values, starting with the initial value and then using ++value
.You can also use std::generate
as an alternative.
因为std::fill
只是将给定的固定值分配给给定范围内的元素[n1,n2)
。并用顺序递增的值std::iota
填充给定范围[n1, n2)
,从初始值开始,然后使用++value
。您也可以使用std::generate
作为替代。
Don't forget that std::iota
is C++11 STL algorithm. But a lot of modern compilers support it e.g. GCC, Clang and VS2012 : http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx
不要忘记那std::iota
是 C++11 STL 算法。但是很多现代编译器都支持它,例如 GCC、Clang 和 VS2012:http: //msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx
P.S. This function is named after the integer function ?
from the programming language APL, and signifies a Greek letter iota. I speculate that originally in APL this odd name was chosen because it resembles an “integer”
(even though in mathematics iota is widely used to denote the imaginary part of a complex number).
PS 此函数以?
编程语言 APL 中的整数函数命名,表示希腊字母 iota。我推测最初在 APL 中选择这个奇怪的名称是因为它类似于 an “integer”
(尽管在数学中 iota 被广泛用于表示复数的虚部)。
回答by James Kanze
My first choice (even in C++11) would be
boost::counting_iterator
:
我的第一选择(即使在 C++11 中)是
boost::counting_iterator
:
std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
boost::counting_iterator<int>( n ) );
or if the vector was already constructed:
或者如果向量已经构建:
std::copy( boost::counting_iterator<int>( 0 ),
boost::counting_iterator<int>( ivec.size() ),
ivec.begin() );
If you can't use Boost: either std::generate
(as suggested in
other answers), or implement counting_iterator
yourself, if
you need it in various places. (With Boost, you can use
a transform_iterator
of a counting_iterator
to create all
sorts of interesting sequences. Without Boost, you can do a lot
of this by hand, either in the form of a generator object type
for std::generate
, or as something you can plug into a hand
written counting iterator.)
如果您不能使用 Boost: 要么std::generate
(如其他答案中所建议的那样),要么counting_iterator
自己实现,如果您在不同的地方需要它。(使用 Boost,您可以使用 atransform_iterator
或 acounting_iterator
来创建各种有趣的序列。如果没有 Boost,您可以手动完成很多工作,无论是以生成器对象类型 for 的形式std::generate
,还是作为可以插入到手写计数迭代器。)
回答by brainsandwich
I've seen the answers with std::generate but you can also "improve" that by using static variables inside the lambda, instead of declaring a counter outside of the function or creating a generator class :
我已经看到了 std::generate 的答案,但您也可以通过在 lambda 内部使用静态变量来“改进”它,而不是在函数外部声明一个计数器或创建一个生成器类:
std::vector<int> vec;
std::generate(vec.begin(), vec.end(), [] {
static int i = 0;
return i++;
});
I find it a little more concise
我觉得它更简洁一些
回答by Frerich Raabe
If you'd rather not use C++11 features, you can use 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;
}
}
This program prints 0 to 9.
该程序打印 0 到 9。
回答by rashedcs
We can use generatefunction which exists in algorithm header file.
我们可以使用存在于算法头文件中的生成函数。
Code Snippet :
代码片段:
#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;
}
回答by pururu
std::iota is limited to a sequence n, n+1, n+2, ...
std::iota 仅限于序列 n, n+1, n+2, ...
But what if you want to fill an array with a generic sequence f(0), f(1), f(2), etc.? Often, we can avoid a state tracking generator. For example,
但是如果你想用通用序列 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);});
will produce the sequence of squares
将产生平方序列
0 1 4 9 16 25 36
However, this trick will not work with other containers.
但是,此技巧不适用于其他容器。
If you're stuck with C++98, you can do horrible things like:
如果你坚持使用 C++98,你可以做一些可怕的事情,比如:
int f(int &x) { int y = (int) (long) &x / sizeof(int); return y*y; }
and then
进而
int a[7];
transform((int *) 0, ((int *) 0) + 7, a, f);
But I would not recommend it. :)
但我不会推荐它。:)
回答by No Idea For Name
this also works
这也有效
j=0;
for(std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it){
*it = j++;
}
回答by no one special
In terms of performance you should initialize the vector with use of reserve()
combined with push_back()
functions like in the example below:
在性能方面,您应该reserve()
结合使用push_back()
以下示例中的函数来初始化向量:
const int numberOfElements = 10;
std::vector<int> data;
data.reserve(numberOfElements);
for(int i = 0; i < numberOfElements; i++)
data.push_back(i);
All the std::fill
, std::generate
, etc. are operating on range of existing vector content, and, therefore the vector must be filled with some data earlier. Even doing the following: std::vector<int> data(10);
creates a vector with all elements set to its default value (i.e. 0 in case of int
).
所有的std::fill
,std::generate
等被操作在现有的矢量含量范围内,且因此所述载体必须充满一些数据早。甚至执行以下操作:std::vector<int> data(10);
创建一个所有元素都设置为其默认值(即 0 的情况下int
)的向量。
The above code avoids to initialize vector content before filling it with the data you really want. Performance of this solution is well visible on large data sets.
上面的代码避免在用你真正想要的数据填充之前初始化矢量内容。该解决方案的性能在大型数据集上非常明显。
回答by King Kokonut
If you reallywant to use std::fill
and are confined to C++98 you can use something like the following,
如果您真的想使用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;
}