通过两个交替的元素混合两个数组

时间:2016-01-27 07:53:08

标签: c++ algorithm

什么是优雅的算法,将两个元素中的元素混合在两个数组中(可能具有不同的大小),以便从每个数组以交替方式绘制项目,并将剩余部分添加到结尾?

E.g。

Array 1:        0, 2, 4, 6

Array 2:        1, 3, 5, 7

Mixed array:    0, 2, 1, 3, 4, 6, 5, 7

不要担心空检查或任何其他边缘情况,我会处理这些问题。 这是我的解决方案,但它无法正常工作:

for (i = 0; i < N; i++) {
     arr[2 * i + 0] = A[i];
     arr[2 * i + 1] = A[i+1]; 

     arr[2 * i + 0] = B[i];
     arr[2 * i + 1] = B[i+1];
}

4 个答案:

答案 0 :(得分:1)

关于循环的一些注释;

  1. 您在结果数组arr中使用相同的位置为其分配两个值(一个来自A,另一个来自B)。
  2. 索引的计算可能比它需要的更复杂,考虑使用两个索引器给定两种方式索引数组。
  3. 我建议您使用一个具有两个索引器(ij)的循环,并显式循环结果的四个元素(即每个输入数组的两个位置)。在每个循环中,您可以适当地递增索引器(输出数组为4,输入数组为2)。

    #include <iostream>
    int main()
    {
        using namespace std;
        constexpr int N = 4;
        int A[N] = {2, 4, 6, 8};
        int B[N] = {1, 3, 5, 7};
        int arr[N*2];
        for (auto i = 0, j=0; i < N*2; i+=4, j+=2) {
             arr[i + 0] = A[j];
             arr[i + 1] = A[j+1];
             arr[i + 2] = B[j];
             arr[i + 3] = B[j+1];
        }
        for (auto i =0; i < N*2; ++i) {
            cout << arr[i] << ",";
        }
        cout << endl;
    }
    

    注意:你提到你处理角落的情况,所以这里的代码要求输入数组长度相同,长度是均匀的。

答案 1 :(得分:1)

显式计算数组索引是非常繁琐的,特别是如果你的数组可能是不同的,可能是奇数长度。如果你保留三个单独的索引,每个数组一个,则更容易:

int pairwise(int c[], const int a[], size_t alen, const int b[], size_t blen)
{
    size_t i = 0;       // index into a
    size_t j = 0;       // index into b
    size_t k = 0;       // index into c

    while (i < alen || j < blen) {
        if (i < alen) c[k++] = a[i++];
        if (i < alen) c[k++] = a[i++];
        if (j < blen) c[k++] = b[j++];
        if (j < blen) c[k++] = b[j++];
    }

    return k;
}

返回值k将等于alen + blen,这是结果数组c的隐式维度。因为为每个数组操作检查下一个项的可用性,所以此代码适用于不同长度的数组,并且当数组具有奇数个元素时。

您可以使用以下代码:

#define countof(x) (sizeof(x) / sizeof(*x))

int main()
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int b[] = {-1, -2, -3, -4, -5, -6};

    int c[countof(a) + countof(b)];
    int i, n;

    n = pairwise(c, a, countof(a), b, countof(b));

    for (i = 0; i < n; i++) {
        if (i) printf(", ");
        printf("%d", c[i]);
    }
    puts("");

    return 0;
}

(示例是在C中,而不是C ++,但是您的代码不使用任何C ++的容器,例如vector,所以我使用了具有显式维度的普通旧'int`数组,这是在C和C ++中也是如此。)

答案 2 :(得分:0)

试试这个:

fragment

没有考虑任何角落案例,只是修复你的概念。例如,检查是否发生任何数组索引超出范围。您可以直播here

答案 3 :(得分:0)

它应该是这样的。

for (i = 0; i < N; i+=2) {
     arr[2 * i + 0] = A[i];
     arr[2 * i + 1] = A[i+1];    
     arr[2 * i + 2] = B[i];
     arr[2 * i + 3] = B[i+1];
}