连接两个数组并将新元素插入数组

Posted

技术标签:

【中文标题】连接两个数组并将新元素插入数组【英文标题】:Concatenating two arrays and inserting a new element to array 【发布时间】:2021-03-18 02:22:45 【问题描述】:

所以我的目标是将两个数组连接在一起,并在数组的开头插入新数组的新大小。例如如果

Arr1 = 5, 1,2,3,4    
and Arr2 = 5, 10, 20, 30, 40 ;

NewArr =  11, 5, 1, 2, 3, 4, 5, 10, 20, 30, 40 

但是,当我运行我的代码时,我得到了

NewArr = 11 1 2 3 4 10 20 30 40 -12851 -12851

看起来我丢失了两个数组中的第一个元素。这是我的代码。

short int* ConcatArray(short int* a1, short int* a2) 
    //size of array 1
    int n = *(a1 + 0);
    //size of array 2
    int m = *(a2 + 0);
    int i;
    int size = n + m;

    short int* newArr = new short int[n + m];

    // increase the size by 1
    size++;

    // shift elements forward 
    for (i = size; i >= 1; i--)
        *(newArr + i) = *(newArr + i - 1);

    // insert x at pos 
    *(newArr + 1 - 1) = size;

    // Create new Array 
    for (i = 1; i < n; i++) 
        *(newArr + i) = *(a1 + i);
    
    
    for (int j = 1; j < m; j++, i++) 
        *(newArr + i) = *(a2 + j);
    
    

    return newArr;

【问题讨论】:

您分配了一个大小为n + m 的数组,但您对顶部for 的第一次迭代访问了n + m + 1(相差2)。顺便说一句,我建议放弃指针算法,只使用数组访问。 你为什么写*(a1 + 0)这样的代码而不是a1[0]?我知道它是有效的,因为这些是数组,所以使用更清晰的数组语法。 “向前移动元素”循环没有意义,它是一个新分配的数组,没有什么可以“移动”的。 我必须为这个赋值使用指针和指针算法 我不只是将元素复制到新数组中,我还必须在新数组的前面添加一个新元素,即新数组的大小。我会试试你的想法@Xenikh 最终数组不应该是9, 1, 2, 3, 4, 10, 20, 30, 40吗?每个源数组的第一个元素是数组大小(正确吗?),因此您不想将这些值复制到最终数组。 【参考方案1】:

假设您希望避免手动编写代码以“1×1”复制数组元素,语言和标准库中有一些工具可以为您做到这一点。

这是现代 C++ 的实现方式:

short* ConcatArray(short* a1, short* a2)

    size_t len1 = a1[0];
    size_t len2 = a2[0];

    short* a3 = new short[len1 + len2 + 1]; // +1 for new length

    *a3 = (short)(len1 + len2 + 1);
    std::copy_n(a1, len1, a3+1);
    std::copy_n(a2, len2, a3 + 1 + len1);

    return a3;

旧的“C”方式(使用新的分配器):

short* ConcatArray(short* a1, short* a2)

    size_t len1 = a1[0];
    size_t len2 = a2[0];

    short* a3 = new short[len1 + len2 + 1]; // +1 for new length

    *a3 = (short)(len1 + len2 + 1);
    memcpy(a3+1, a1, sizeof(*a1)*len1);
    memcpy(a3+1+len1, a2, sizeof(*a2)*len2);


    return a3;

【讨论】:

这也可能是std::copy_n 的情况。区别主要是表面上的,但有些人可能认为它更清楚。 @Blastfurnace - 同意。 copy_n 确实看起来更好。谢谢。 谢谢,我遇到的唯一问题是没有从数组 2 中获取最后一个值 @StephDev - 我有一个错字。而不是*a3 = (short)(len1 + len2); 应该是*a3 = (short)(len1 + len2 + 1); 这已在上面修复。【参考方案2】:

如果您首先将值复制到正确的位置,则无需移动它们。这应该可以满足您的需求。

short int *ConcatArray(short int *a1, short int *a2)

    short int n = a1[0]; // size of array 1
    short int m = a2[0]; // size of array 2
    short int newSize = n + m + 1;

    short int *newArr = new short int[newSize];

    int i = 0; // current output position in newArr
    newArr[i++] = newSize;

    for (int j = 0; j < n; ++j, ++i)  // copy a1
        newArr[i] = a1[j];
    

    for (int j = 0; j < m; ++j, ++i)  // copy a2
        newArr[i] = a2[j];
    

    return newArr;

这是Compiler Explorer 上的代码。

【讨论】:

我仍然遇到与以前相同的问题,两个原始数组中的前两个元素不在新数组中。谢谢你帮助我 @StephDev 你想要新数组中的 5 个值吗?这是我刚刚做出的一个简单更改。 是的,请,我们允许有重复,所以在数组中有两个相同的数字是可以的。 由于某种原因,我仍然没有从两个数组中获得 5 个值 @StephDev 代码确实有效。你可以看到它编译并运行,here on Compiler Explorer.

以上是关于连接两个数组并将新元素插入数组的主要内容,如果未能解决你的问题,请参考以下文章

数组的剩余方法

从 in[] 数组中获取元素并将它们连接起来的算法[关闭]

比较两个对象数组,并将匹配值的元素排除到JS中的新数组中

2022-09-11:arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”, 并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。 我们最多能将数组分成

如何连接两个指向字符串的指针并将其存储在数组或字符中?

js中不会影响原数组的方法