将两个数组排序为组合数组

Sorting two arrays into a combined array

本文关键字:数组排序 组合 数组 两个      更新时间:2023-10-16

我已经好几年没有上过任何编程课了,所以请原谅任何初学者在做某事时的错误/方法。我很乐意为未来提出建议。使用下面的代码,我试图检查两个数组(已经排序)的值,并将它们放入一个组合数组中。我的解决方案,无论效率多么低下/草率,都是使用for循环来比较j处每个数组索引的内容,然后将较低的值分配给组合数组的索引i,将较高的值分配到索引i+1。我将I增加2以避免覆盖上一个循环的索引。

int sortedArray1 [5] = {11, 33, 55, 77, 99};
int sortedArray2 [5] = {22, 44, 66, 88, 00};
combinedSize = 10;
int *combinedArray;
combinedArray = new int[combinedSize];
for(int i = 0; i <= combinedSize; i+=2)
{
for(int j = 0; j <= 5; j++)
{
if(sortedArray1[j] < sortedArray2[j])
{
combinedArray[i] = sortedArray1[j];
combinedArray[i+1] = sortedArray2[j];
}
else if(sortedArray1[j] > sortedArray2[j])
{
combinedArray[i] = sortedArray2[j];
combinedArray[i+1] = sortedArray1[j];
}
else if(sortedArray1[j] = sortedArray2[j])
{
combinedArray[i] = sortedArray1[j];
combinedArray[i+1] = sortedArray2[j];
}
}
}
for(int i = 0; i < combinedSize; i++)
{
cout << combinedArray[i];
cout << " ";
}

我的结果是这个

Sorted Array 1 contents: 11 33 55 77 99
Sorted Array 2 contents: 0 22 44 66 88
5 77 5 77 5 77 5 77 5 77 Press any key to continue . . .

在我缺乏经验的头脑中,排序的实现看起来不错,所以我不确定为什么我会得到这样糟糕的输出。建议太棒了。

这个呢:

int i=0,j=0,k=0;
while(i<5 && j<5)
{
if(sortedArray1[i] < sortedArray2[j])
{
combinedArray[k]=sortedArray1[i];
i++;
}
else
{
combinedArray[k]=sortedArray2[j];
j++;
}
k++;
}
while(i<5)
{
combinedArray[k]=sortedArray1[i];
i++;k++;
}
while(j<5)
{
combinedArray[k]=sortedArray2[j];
j++;  k++;
}

首先,如何使用C++:存在一些直接的问题

  • 您使用=而不是==进行相等性检查(因此会导致不需要的值赋值,并且if条件在不应该返回true时返回true)
  • 外循环的上边界定义为i <= 10,而正确的边界检查为i < 10
  • 由于未能取消分配内存,因此函数末尾出现内存泄漏。你最后需要一个delete [] combinedArray

其次,外循环遍历目标数组的所有值,并且在每个步骤中都使用一个内循环遍历源阵列的所有值。这不是你想要的。您想要的是一个循环j=0计数到j<5,并在源数组中迭代。然后,目的地阵列中的位置被确定为2*j2*j+1,并且不需要内部循环。

第三,正如评论中所解释的,排序列表合并的正确实现需要两个独立的计数器j1j2。但是,您的当前输入是硬连接到代码中的,如果您用100替换00,则您的当前算法(在进行上述更正之后)将实际适用于给定的输入。

最后,但不太重要的是,我想知道为什么要使用new在堆上分配目标数组。只要您处理的是小数组,就可以像源数组一样在堆栈上分配它。但是,如果在堆上分配它,最好使用std::unique_ptr<>,可能与std::array<>组合使用。您将免费获得取消分配,而无需考虑在函数末尾放置delete []语句。

在查看实现之前,请检查算法并用笔和纸写下来。弹出的第一件事是,假设结果中的前两个元素将来自每个源数组。不一定是这样,考虑两个阵列,其中一个阵列中的所有元素都小于另一个阵列的所有元素,以及预期结果:

int a[] = { 1, 2, 3 };
int b[] = { 4, 5, 6 };

如果要对结果进行排序,那么前三个元素都来自第一个数组。考虑到这一点,想想你对数据的真正了解。特别地,两个数组都被排序,这意味着第一个元素将小于相应数组中的其余元素。这意味着元素越小,头部就越小。通过将该元素放入结果中,您将问题减少到了一个较小的集合中。您有a' = { 2, 3 }b = { 4, 5, 6 }res = { 1 },还有一个新问题,即在知道a'b已排序的情况下找到res的第二个元素。

在纸上弄清楚你需要做什么,然后应该直接将其映射到代码中。

因此,我修改了您的代码以使其工作。实际上,最好为两个排序的数组设置两个指针/索引。这样,您就可以在将相应的指针添加到组合数组后更新它。如果您不理解此代码的任何部分,请告诉我。谢谢

int sortedArray1 [5] = {11, 33, 55, 77, 99};
int sortedArray2 [5] = {0, 22, 44, 66, 88}; 
int combinedSize = 10;
int *combinedArray;
combinedArray = new int[combinedSize];
int j = 0;
int k = 0;
for(int i = 0; i < combinedSize; i++)
{
if (j < 5 && k < 5) {
if (sortedArray1[j] < sortedArray2[k]) {
combinedArray[i] = sortedArray1[j];
j++;
} else {                  
combinedArray[i] = sortedArray2[k];
k++;
}                         
} 
else if (j < 5) {
combinedArray[i] = sortedArray1[j];
j++;
}                         
else {
combinedArray[i] = sortedArray2[k];
k++;
}                         
}
for(int i = 0; i < combinedSize; i++)
{
cout << combinedArray[i];
cout << " ";
}
cout<<endl;

else if(sortedArray1[j] = sortedArray2[j]),你是指else if(sortedArray1[j] == sortedArray2[j])吗?

前者将sortedArray2[j]的值分配给sortedArray1[j]——这就是为什么您得到5 77 5 77...的原因

但是5是从哪里来的?sortedArray中都没有5,但我发现for(int j = 0; j <= 5; j++)一定有问题。大小为N的数组的最高索引是N-1,而不是C/C++中的N(但不是Basic中的)。。所以用j<5作为条件,否则你可能会陷入难以解释或预测的境地。。

毕竟,算法本身存在问题,每次外循环循环时,它最终都会比较两个数组中的最后一个元素,这使得输出重复两个数字。

因此,您也需要更正您的算法,请参阅合并排序。

略有不同的方法,这使IMHO更干净:

//A is the first array, m its length
//B is the second array, n its length
printSortedAndMerged(int A[], int m, int B[], int n){
int c[n+m];
int i=0, j=0;
for(int k=0; k < n+m; k++){
if(i < m && j < n){
if(A[i] < B[j]){
c[k] = A[i];
i++;
}
else{
c[k] = B[j];
j++;
}
continue; //jump to next iteration
}
if(i < m){ // && ~(j < n)
//we already completely traversed B[]
c[k] = A[i];
i++;
continue;
}
if(j < n){ // %% ~(i < m)
//we already completely traversed A[]
c[k] = B[j];
j++;
continue;
}
//we should never reach this
cout << "Wow, something wrong happened!" << endl;
}//for
for(int i=0; i<n+m; i++){
cout << c[i] << endl;
}
}

希望能有所帮助。