Java中如何合并和排序两个数组?

4

基本上,有两个单独的预排序数组,你需要将它们合并并排序(当然不能使用sort()方法)。以下是我的代码:

public static void main(String[] args) {

    int a [] = {3,5,7,9,12,14, 15};
    int b [] = {6 ,7, 10};
    int j = 0;

    //output array should be 3,5,6,7,7,9,10,12,14,15

    int c [] = new int[a.length+b.length];//10 values

    for (int i = 0;i<b.length;i++){
        while(b[i]>a[j]){
            c[j] = a[j] ;
            j++;    
         }

        if(b[i] == a[j]){
            c[j] = b[i];
            c[j+1] = a[j];
        }

        c[j] = b[i];
        j++;
    }

    for(int i = 0;i<c.length;i++)
        System.out.println(c[i]);
    }

我猜测我得到的零是由于布尔值中的错误(< & >),但我似乎无法弄清楚。前四个是正常的,但一旦到达重复的7,它就变得疯狂了。
请帮助我理解,而不只是更改代码。

我猜这是为了作业吧? - smcg
1
可能是与此问题重复:https://dev59.com/5W025IYBdhLWcg3whGWx。 - Ben.Vineyard
2
除了搜索已有的带有答案的问题以回答您的问题外,请在所有与作业相关的问题上附加一个标签“作业”。这有助于我们知道给您提示来帮助您学习而不仅仅是答案。 - BlackVegetable
6个回答

6
这是一个简单易懂的解释:

以下是它应该如何呈现:

public static void main(String[] args) {

    int a [] = {3,5,7,9,12,14, 15};
    int b [] = {6 ,7, 10};
    int j = 0, k = 0;

    //output array should be 3,5,6,7,7,9,10,12,14,15

    int c [] = new int[a.length+b.length];//10 values

    // we're filling c with the next appropriate number
    // we start with checking a[0] and b[0] till we add
    // all the elements
    for (int i = 0; i < c.length; i++) {
        // if both "a" and "b" have elements left to check
        if (j < a.length && k < b.length) {
            // check if "b" has a smaller element
            if (b[k] < a[j]) {
                // if so add it to "c"
                c[i] = b[k];
                k++;
            }
            // if "a" has a smaller element
            else {
                // add it to "c"
                c[i] = a[j];
                j++;
            }       
        }
        // if there are no more elements to check in "a"
        // but there are still elements to check in "b"
        else if (k < b.length) {
            // add those elements in "b" to "c"
            c[i] = b[k];
            k++;
        }
        // if there are no more elements to check in "b"
        // but there are still elements to check in "a"
        else {
            // add those elements in "a" to "c"
            c[i] = a[j];
            j++;
        }
    }

    for(int i = 0; i < c.length; i++)
        System.out.println(c[i]);
}

希望这能有所帮助。

1
你可以尝试这段代码。
public static void main(String[] args) {
    int a[] = { 3, 5, 7, 9, 12, 14, 15 };
    int b[] = { 6, 7, 10 };

    // output array should be 3,5,6,7,7,9,10,12,14,15

    int alen = a.length;
    int blen = b.length;
    int c[] = new int[a.length + b.length];// 10 values

    int s[] = null;
    int[] l = null;

    if (alen < blen) {
        s = a;
        l = b;
    } else {
        s = b;
        l = a;
    }
            // Constructing Combined Array
    for (int i = 0, p = 0; i < c.length; i++, p++) {
        if (i == s.length) {
            p = 0;
        }
        if (i < s.length) {
            c[i] = s[p];
        } else {
            c[i] = l[p];
        }
    }
            //Sorting the C array 
    for (int i = 1; i < c.length; i++) {
        int j = i;
        int B = c[i];
        while ((j > 0) && (c[j - 1] > B)) {
            c[j] = c[j - 1];
            j--;
        }
        c[j] = B;
    }

    for (int i = 0; i < c.length; i++)
        System.out.print(c[i]);
}

为什么需要 int s[] = null; int[] l = null; - ilalex
s[] 用于存储较小的数组,l[] 用于存储较大的数组。如果我们知道哪个数组更小,我们可以轻松地构建 c(合并)。 - Akhi

0
尝试这个,你的错误是你正在使用相同的单元索引来访问数组A和数组C:
public class MainClass {
      public static void main(String[] args) {
        int[] arrayA = { 23, 47, 81, 95 };
        int[] arrayB = { 7, 14, 39, 55, 62, 74 };
        int[] arrayC = new int[10];

        merge(arrayA, arrayA.length, arrayB, arrayB.length, arrayC);
        for (int i : arrayC) {
          System.out.println(i);

        }
      }

      public static void merge(int[] arrayA, int sizeA, int[] arrayB, int sizeB, int[] arrayC) {
        int arrayAIndex = 0, arrayBIndex = 0, arrayCIndex = 0;

        while (arrayAIndex < sizeA && arrayBIndex < sizeB)
          if (arrayA[arrayAIndex] < arrayB[arrayBIndex])
            arrayC[arrayCIndex++] = arrayA[arrayAIndex++];
          else
            arrayC[arrayCIndex++] = arrayB[arrayBIndex++];

        while (arrayAIndex < sizeA)
          arrayC[arrayCIndex++] = arrayA[arrayAIndex++];

        while (arrayBIndex < sizeB)
          arrayC[arrayCIndex++] = arrayB[arrayBIndex++];
      }
    }

这是另一个版本

// size of C array must be equal or greater than
// sum of A and B arrays' sizes
public void merge(int[] A, int[] B, int[] C) {
      int i, j, k, m, n;
      i = 0;
      j = 0;
      k = 0;
      m = A.length;
      n = B.length;
      while (i < m && j < n) {
            if (A[i] <= B[j]) {
                  C[k] = A[i];
                  i++;
            } else {
                  C[k] = B[j];
                  j++;
            }
            k++;
      }
      if (i < m) {
            for (int p = i; p < m; p++) {
                  C[k] = A[p];
                  k++;
            }
      } else {
            for (int p = j; p < n; p++) {
                  C[k] = B[p];
                  k++;
            }
      }
}

你看到他们的评论了吗:“请帮助我理解,不要只是更改代码”?你能详细说明一下他们当前的代码有什么问题吗? - Leigh
问题在于他正在使用同一个变量j来指向选项卡a和选项卡c的单元格索引。 - K_Anas

0
实际上更好的说法是合并(而不是组合)两个数组。
将已排序的数组A和B [0..n-1] 合并成结果C [0..m+n-1] 的简单算法(取自此 article )。
  1. 引入读索引ij来遍历数组A[0..m-1]B。引入写索引k来存储结果数组中第一个空闲单元的位置。默认情况下,i = j = k = 0。
  2. 在每个步骤中:如果两个索引都在范围内(i < mj < n),选择最小值(A[i]B[j])并将其写入C[k]。否则,转到步骤4。
  3. 增加k和算法所在的数组的索引,该算法定位到最小值,并重复步骤2。
  4. 将仍在范围内的数组中的其余值复制到结果数组中。

希望对您有所帮助。


2
简单的链接应该作为评论,而不是答案。 - peacemaker
2
请在您的答案中提供一些实质性内容,而不仅仅是相关内容的链接。 - pb2q
@peacemaker从文章中复制并粘贴了算法。现在可以了吗? :) - ArtemStorozhuk

0

在源数组中使用aibi作为索引,在目标数组中使用ci作为索引。

你只需要一个循环。

尝试保持非常清晰,并且在每次迭代中恰好向前移动一个元素。

在循环中,检查是否到达了一个数组的末尾。如果是这样,只需从另一个数组中取一个元素。否则,只取a[ai]b[bi]中较小的元素并递增相应的索引。

在归并排序(或任何需要并行遍历两个数组的代码)中很容易犯错误,认为“嘿,我可以用while循环来代替单个if”,但是这通常会导致三个嵌套循环,对于每个循环,您都必须进行正确的边界检查,并且通常没有显着的性能提升。

附:在主循环之后执行两个清理循环是可以的,只要避免不必要的嵌套循环,特别是在面试中,这可能会在计算运行时间时造成混淆。


0
public class Combinearray {

    public static void main(String[] args) {
        int[] array1= {5,4,6,2,1};
        int[] array2= {2,5,8,4,1,6,4};
        int m=array1.length;
        int n=array2.length;
        int[] array3=new int[m+n];
        int a=1;
        for(int i=0;i<m;i++) {

            array3[i]=array1[i];//array1 is copied to array3
        }
        for(int i=0;i<n;i++) {
            array3[m-1+a]=array2[i];//array2 is copied to array3
            a++;
        }
        //array3 is combined array
         int l=array3.length;
            int temp[]=new int[l];
            for(int i=0;i<l;i++) {
                for(int j=i+1;j<l;j++) {
                    if(array3[i]>array3[j]) {
                        temp[i]=array3[i];
                        array3[i]=array3[j];
                        array3[j]=temp[i];
                    }
                }
            }
            System.out.println("sorted array is ");
            System.out.print("[");
            for(int i=0;i<l;i++) {
                System.out.print(array3[i]+" ");  
            }
            System.out.print("]");

    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接