Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.5k views
in Technique[技术] by (71.8m points)

c++ - Copy every other element using standard algorithms (downsampling)

say I have a std::vector with N elements. I would like to copy every n-th element of it to a new vector, or average up to that element then copy it (downsample the original vector). So I want to do this

std::vector<double> vec(N);
long n = 4;
std::vector<double> ds(N/n);
for(long i = 0; i < ds.size(); i+=n)
{
    ds[i] = vec[i*n];
}

or

for(long i = 0; i < ds.size(); i+=n)
{
    double tmp = 0;    
    for(long j = 0; j < n; j++)
    {
        tmp += vec[i*n+j];
    }
    ds[i] = tmp/static_cast<double>(n);
}

Is there a way to do this using the standard algorithms of C++? Like using std::copy with binary functions? I have billions of elements that I want to treat this way, and I want this to be as fast as possible.

PS: I would prefer not to use external libraries such as boost.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For readability, the loop would be a good idea, as pointed out by Vlad in the comments. But if you really want to do someting like this, you could try:

int cnt=0,n=3; 
vector<int> u(v.size()/3); 
copy_if (v.begin(), v.end(), u.begin(), 
          [&cnt,&n] (int i)->bool {return ++cnt %n ==0; } ); 

If you want to average, it's getting worse as you'd have to similar tricks combining transform() with copy_if().

Edit: If you're looking for performance, you'd better stick to the loop, as stressed in the comments by davidhigh: it will avoid the overhead of the call to the lambda function for each element.

If you're looking for an algorithm because you're doing this very often, you'd better write your own generic one.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...