合并长度不等的排序数组

Posted

技术标签:

【中文标题】合并长度不等的排序数组【英文标题】:Merging sorted arrays of unequal length 【发布时间】:2016-02-06 04:39:15 【问题描述】:

我有一个项目需要我合并两个排序数组(a 和 b)并将结果放入长度为 a.length + b.length 的新数组中。 我正在跟踪我在所有 3 个数组中的位置的计数器,并且我的数组的长度不相等。我的约定是,如果一个数组先于另一个用完,代码会将另一个数组的其余部分转储到结果数组中。

不幸的是,我可以检查另一个数组是否仍然包含元素的唯一方法是查看 for 循环。

谁能帮帮我?这应该是一个相对容易解决的问题,但我想不出解决方案。

public class Two 
    public static void main(String[] args) 
        //sample problem
        int[] var_a = 2,3,5,5,8,10,11,17,18,20; 
        int[] var_b = 5,6,7,8,14,15,17;
        final int a_size = 10;
        final int b_size = 7;
        final int c_size = 17; 
        int[] var_c = new int[17];

        int aCount = 0;
        int bCount = 0;
        int cCount = 0;
        for (cCount = 0; cCount < c_size; cCount++) 
            //b runs out before a runs out
            if ((bCount == b_size) && (aCount <= a_size)) 
                //dump rest of var_a into var_c     
                var_c[cCount] = var_a[aCount];
                aCount++;
            
            //PROBLEM: bCount is equal to bSize, and is triggering the break.
            //a runs out before b runs out
            else if ((aCount == a_size) && (bCount <= b_size)) 
                //dump rest of var_b into var_c
                var_c[cCount] = var_b[bCount];
                bCount++;
            

            if ((aCount >= a_size) || (bCount >= b_size) || (cCount >= c_size)) break;

            if (var_a[aCount] < var_b[bCount]) 
                var_c[cCount] = var_a[aCount];
                aCount++;
             else if (var_a[aCount] > var_b[bCount]) 
                var_c[cCount] = var_b[bCount];
                bCount++;
             else if (var_a[aCount] == var_b[bCount]) 
                var_c[cCount] = var_a[aCount];
                aCount++;
                cCount++;
                var_c[cCount] = var_b[bCount];
                bCount++;
            
        
        for (int i : var_c) 
            System.out.print(i + " ");
        
    

【问题讨论】:

你忘了问一个实际问题吗? 【参考方案1】:

此问题的常见解决方案是将单个循环替换为三个:

第一个循环合并两个数组,直到其中一个用完元素 第二个循环将数组A 的剩余元素(如果有)转储到输出数组中 第三个循环将数组B 的剩余元素(如果有)转储到输出数组中

这种结构可以让合并循环变得更简单:

while (aCount != var_a.length() && b.Count != var_b.length()) 
    ... // merge

while (aCount != var_a.length()) 
    var_c[cCount++] = var_a[aCount++];

while (bCount != var_b.length()) 
    var_c[cCount++] = var_b[bCount++];

请注意,最后两个循环中最多执行一个。还要注意使用length() 方法来确定数组的长度。比设置a_sizeb_size等更可靠。

【讨论】:

这很有帮助!非常感谢:)【参考方案2】:

这段代码应该遵循一个简单的逻辑

    将所有 3 个 a_counter、b_counter、c_c 的计数器初始化为 0 现在直到 a_c 或 b_counter 分别小于 a_size 和 b_size 比较 a[a_counter] 和 b[b_counter] 并将较小的添加到 c 的 c[c_counter] 增加 c_counter,以及上面选择的那个 重复 一旦脱离循环,a 或 b 之一结束 如果 b 结束,则继续将 a 的所有剩余元素添加到 c;或 b 如果 a 结束 我相信您不需要代码,只需改进逻辑即可;所以不给代码。

【讨论】:

【参考方案3】:

您可以遍历单个数组的索引,而不是迭代合并数组的索引,以确保您永远不会超出范围:

int aCount = 0;
int bCount = 0;
int cCount = 0;
while (aCount < var_a.length && bCount < var_b.length) 
    if (var_a[aCount] <= var_b[bCount]) 
        var_c[cCount++] = var_a[aCount++];
     else 
        var_c[cCount++] = var_b[bCount++];
    

// now add what remains of var_a or var_b
while (aCount < var_a.length)
    var_c[cCount++] = var_a[aCount++];
while (bCount < var_b.length)
    var_c[cCount++] = var_b[bCount++];

【讨论】:

【参考方案4】:

这可能就是你想要的:

void doArrayThing()
    //the two arrays containing the elements
    int[] array1 = 1, 3, 5, 2, 7, 5;
    int[] array2 = 3, 6, 2, 8;

    //the length of the 2 arrays
    int arrayLength1 = array1.length;
    int arrayLength2 = array2.length;

    //the length of both the arrays
    int containerArrayLength = arrayLength1 + arrayLength2;

    //the array that holds all the elements
    int[] container = new int[containerArrayLength];

    //a for loop that adds the first array elements
    for(int i = 0; i < arrayLength1; i++)
        //add the elements of the first array
        container[i] = array1[i];
    

    //the for loop that adds the second array elements
    for(int i = 0; i < arrayLength2; i++)
        //add the second array elements on top of the first
        container[i + arrayLength1] = array2[i];
    

    for(int i = 0; i < containerArrayLength; i++)
        //print all the elements
        System.out.println(container[i]);
    

它的作用:

它遍历第一个数组并添加数字,然后遍历第二个数组并将元素添加到第一个数组元素的顶部。

【讨论】:

这看起来不错,但如果容器数组是迭代排序的,而不使用任何方法,我会喜欢它。不过我完全理解你在做什么。【参考方案5】:

您的算法看起来基本正确。如果没有运行确切的代码,我认为您的问题主要是您的等式太多,即几乎每个比较都是等于、小于等于、大于等于。

如果a==b,那么a=b。因此,您的 if 语句匹配太多。密切关注具体的索引应该是什么,并将您的案例限制在它们应该是什么。

我已经重写了你的代码(抱歉,没有编辑器,所以它可能无法开箱即用),这应该会给你一个很好的主意。

public class Two 

    public static void main(String[] args) 
    
        //sample problem
        int[] arrayA = 2,3,5,5,8,10,11,17,18,20; 
        int[] arrayB = 5,6,7,8,14,15,17;
        final int sizeA = arrayA.length();
        final int sizeB = arrayB.length();
        final int sizeC = sizeA+sizeB; 
        int[] arrayC = new int[sizeC];
        int countA = 0;
        int countB = 0;
        int countC = 0;
        for (countC = 0; countC < sizeC; countC++)
        
            // if a has run out, fill with b
            if (countA == sizeA && countB < sizeB)
            
                arrayC[countC] = arrayB[countB];
                countB++;
            
            // if b has run out, fill with a
            else if (countA < sizeA && countB == sizeB)
            
                arrayC[countC] = arrayA[countA];
                countA++;
            
            // countA < sizeA && countB < sizeB because 
            // if countA == sizeA && countB == sizeB then also countC == sizeC 
            // and the for-loop would have stopped.
            else        
            
                // mind, if arrayA[countA] == arrayB[countB] then first 
                // a will be added and on the next pass b will be added
                if (arrayA[countA] <= arrayB[countB])
                
                    arrayC[countC] = arrayA[countA];
                    countA++;
                
                else
                
                    arrayC[countC] = arrayB[countB];
                    countB++;
                
            
        
    

【讨论】:

以上是关于合并长度不等的排序数组的主要内容,如果未能解决你的问题,请参考以下文章

两条曲线之间的二维插值(长度不等的数组)

输入n个数组,数组长度不等,每个数组取出一个数进行组合,求出所有的组合。

算法 - 合并两个有序数组成一个有序数组

算法 - 合并两个有序数组成一个有序数组

四边形不等式(石子合并)

C语言判断两个长度不等的字符数组是不是相等的方法