7

是否有更有效的方法来获取数组的每一秒(通常是每 N 个)元素,然后是下面的简单 for 循环?例如使用通用算法?

#include<iostream>
using namespace std;

int main()
{
    const int a_size = 6, b_size = 3;
    int a[a_size] = {1, 3, 6, 3, 2, 7}; 
    int b[b_size];
    int bx = 0;
    for ( int ax = 0; ax < a_size; ++ax )
    {   
        if (ax % 2 == 0)
            b[bx++] = a[ax];  
    }   
}
4

6 回答 6

14
for (int ax = 0; ax < a_size; ax += 2)

只是要小心,如果a_size接近INT_MAX

于 2013-08-11T16:44:31.193 回答
2

一个循环应该足够好。正如皮特指出的那样,您可以避免模测试。

 for (int ax = 0; ax < a_size; ax += 2)
   ...

C++ 通过valarray标头提供对切片的支持(例如,看看std::slice_array)。

我不知道这是否是你要找的。它适用于重量级数值计算。如果您不确定,我认为简单的循环是正确的答案。

于 2013-08-11T16:54:15.673 回答
2

如果高效,你的意思是更快,内存占用更小,那么我会选择使用指针而不是数组访问。例如,您想要的可以用指针通过以下方式实现。

int main() {
    const int a_size = 6, b_size = 3;
    int a[a_size] = {1, 3, 6, 3, 2, 7}; 
    int b[b_size];
    int* a_ptr = a;
    int* a_end_ptr = a_ptr + a_size;
    int* b_ptr = b;
    while(a_ptr < a_end_ptr) {
        *b_ptr = *a_ptr;
        b_ptr++;
        a_ptr += 2;
    }
}

这个示例应该比数组访问示例稍微快一些,我鼓励您自己计时并查看。但是,在进行这些优化时,您应该始终注意的一件事是查看它在程序的大型方案中是否重要(不要在不必要的时候花时间)。

于 2013-08-11T17:09:38.063 回答
1

这是最快的:

void copy_n(int & a[], int & b[], int a_sz, int n) {
  int bx = 0;
  for (int i=0; i<a_sz; i+=n) {
    b[bx++]=a[i];
  }
}
于 2013-08-11T17:29:57.613 回答
1

您可以轻松地创建一个every_n谓词并使用它来根据需要过滤 copy_if 等。这是您可以获得的通用性。

“每 n 个元素”谓词的近似(注意:尚未测试)示例:

/**
 @brief Un predicado que retorna @c true cada @a n invocaciones.
**/
template <typename Integer>
struct every_n {
    static_assert (std::numeric_limits<Integer>::is_integer, "Must behave like an integer");
    public:
    explicit every_n (Integer const& e)
    : n(e), x(1) {}

    every_n (every_n const& E)
    : n(E.n), x(E.x) {}

    bool operator () (...) {
        if (x<n) { ++x; return false; }
        else { x=Integer(1); return true; }
    }

    private:
    Integer x;
    const Integer n;
};

// "make_" idiom
template <typename Integer>
every_n<Integer> every (Integer const& c) { return every_n<Integer>(c); }


// sample usage
# include required headers, etc
using namespace std;
const int a_size = 6, b_size = 3;
int a[a_size] = {1, 3, 6, 3, 2, 7}; 
int b[b_size];
copy_if (begin(a), end(a), begin(b), every(3));

所需要的所有代码都是every()使用行为类似于整数的类型调用的。

(代码使用 static_assert、begin()、end() 和 copy_if(),它们是 C++11,但如果你像我一样向后移植足够的函数,那么在 C++03 中的功能也一样)

于 2013-08-11T17:05:31.003 回答
0

例子:

#include<iostream>
using namespace std;

int main() {
    const int a_size = 6;
    const int b_size = a_size / 2;

    int a[a_size] = {1, 3, 6, 3, 2, 7}; 
    int b[b_size];

    for (int ax = 0, bx = 0; ax < a_size; ax += 2) {
        b[bx++] = a[ax];
    }   
}
于 2013-08-11T16:56:45.573 回答