C++中数组的每个n元素

Every n element of an array in C++

本文关键字:元素 数组 C++      更新时间:2023-10-16

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

#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];  
    }   
}
for (int ax = 0; ax < a_size; ax += 2)

如果a_size接近INT_MAX,请小心。

循环应该足够好。正如Pete所指出的,你可以避免模测试。

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

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

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

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

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;
    }
}

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

您可以轻松地创建一个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(

这是最快的:

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];
  }
}

示例:

#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];
    }   
}