连接两个数组并将新元素插入数组
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.以上是关于连接两个数组并将新元素插入数组的主要内容,如果未能解决你的问题,请参考以下文章
2022-09-11:arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”, 并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。 我们最多能将数组分成