简体   繁体   English

创建一种方法,将 2 arrays 合并到一个按升序排序的数组中 Java

[英]Creating a method that merges 2 arrays into one sorted array in ascending order in Java

For part of an assignment, I have to create a method that merges 2 arrays into one sorted array in ascending order.对于作业的一部分,我必须创建一种方法,将 2 arrays 按升序合并到一个排序数组中。 I have most of it done, but I am getting a bug that replaces the last element in the array with 0. Has anyone ever run into this problem and know a solution?我已经完成了大部分工作,但是我遇到了一个错误,它将数组中的最后一个元素替换为 0。有没有人遇到过这个问题并知道解决方案? Heres my code:这是我的代码:

     public static OrderedArray merge(OrderedArray src1, OrderedArray src2) {

         int numLength1 = src1.array.length;
         int numLength2 = src2.array.length;
         
         //combined array lengths
         int myLength = (numLength1 + numLength2);
        // System.out.println(myLength);
         OrderedArray mergedArr = new OrderedArray(myLength);
         
         //new array
         long[] merged = new long[myLength];
         
         //loop to sort array
         int i = 0;
         int j = 0;
         int k = 0;
         while (k < src1.array.length + src2.array.length - 1) {
             if(src1.array[i] < src2.array[j]) {
                 merged[k] = src1.array[i];
             i++;
             }
             else {
                merged[k] = src2.array[j];
             j++;
                 
             }
            k++; 
            
         }
         
         //loop to print result
         for(int x = 0; x < myLength; x++) {
             System.out.println(merged[x]);
         }
         return mergedArr;
     }

    public static void main(String[] args) {
        int maxSize = 100; // array size
//      OrderedArray arr; // reference to array
        OrderedArray src1 = new OrderedArray(4);
        OrderedArray src2 = new OrderedArray(5);


        
//      arr = new OrderedArray(maxSize); // create the array
        
        
        src1.insert(1);  //insert src1
        src1.insert(17);
        src1.insert(42);
        src1.insert(55);
    
        
        src2.insert(8); //insert src2
        src2.insert(13);
        src2.insert(21);
        src2.insert(32);
        src2.insert(69);
        
        OrderedArray myArray = merge(src1, src2);

This is my expected output:这是我预期的 output:

1
8
13
17
21
32
42
55
69

and this is my current output:这是我现在的 output:

1
8
13
17
21
32
42
55
0

While merging two arrays you are comparing them, sorting and merging but what if the length of two arrays is different like Array1{1,3,8} and Array2{4,5,9,10,11}.在合并两个 arrays 时,您正在对它们进行比较、排序和合并,但是如果两个 arrays 的长度不同,如 Array1{1,3,8} 和 Array2{4,5,9,10,11} 怎么办。 Here we will compare both arrays and move the pointer ahead, but when the pointer comes at 8 in array1 and at 9 in array2, now we cannot compare ahead, so we will add the remaining sorted array;这里我们将两个arrays进行比较,并将指针向前移动,但是当指针到达array1中的8和array2中的9时,现在我们不能向前比较,所以我们将添加剩余的排序数组;

Solution:-解决方案:-

(Add this code between loop to sort array and loop to print array) (在循环之间添加此代码以对数组进行排序和循环以打印数组)

        while (i < numLength1) {
            merged[k] = src1.array[i];
            i++;
            k++;
        }

        while (j < numLength2) {
            merged[k] = src2.array[j];
            j++;
            k++;
        }

To answer your main question, the length of your target array is src1.array.length + src2.array.length , so your loop condition should be one of:要回答您的主要问题,目标数组的长度是src1.array.length + src2.array.length ,因此您的循环条件应该是以下之一:

  • while (k < src1.array.length + src2.array.length) {
  • while (k <= src1.array.length + src2.array.length - 1) {

Otherwise, you will never set a value for the last element, where k == src1.array.length + src2.array.length - 1 .否则,您永远不会为最后一个元素设置值,其中k == src1.array.length + src2.array.length - 1

But depending on how comprehensively you test the code, you may then find you have a bigger problem: ArrayIndexOutOfBoundsException .但是,根据您测试代码的全面程度,您可能会发现遇到更大的问题: ArrayIndexOutOfBoundsException Before trying to use any array index, such as src1.array[i] , you need to be sure it is valid.在尝试使用任何数组索引之前,例如src1.array[i] ,您需要确保它是有效的。 This condition:这种情况:

if(src1.array[i] < src2.array[j]) {

does not verify that i is a valid index of src1.array or that j is a valid index of src2.array .不验证isrc1.array的有效索引或jsrc2.array的有效索引。 When one array has been fully consumed, checking this condition will cause your program to fail.当一个数组已被完全消耗时,检查此条件将导致您的程序失败。 You can see this with input arrays like { 1, 2 } & { 1 } .您可以通过输入 arrays 看到这一点,例如{ 1, 2 } & { 1 }

This revision of the code does the proper bounds checks:此代码修订版进行了适当的边界检查:

if (i >= src1.array.length) {
    // src1 is fully consumed
    merged[k] = src2.array[j];
    j++;
} else if (j >= src2.array.length || src1.array[i] < src2.array[j]) {
    // src2 is fully consumed OR src1's next is less than src2's next
    merged[k] = src1.array[i];
    i++;
} else {
    merged[k] = src2.array[j];
    j++;
}

Note that we do not need to check j in the first condition because i >= src1.array.length implies that j is a safe value, due to your loop's condition and the math of how you are incrementing those variables:请注意,我们不需要在第一个条件下检查j因为i >= src1.array.length意味着j是一个安全值,因为你的循环条件和你如何递增这些变量的数学:

  • k == i + j due to parity between k's incrementing and i & j's mutually exclusive incrementing k == i + j由于 k 的递增和 i & j 的互斥递增之间的奇偶校验
  • k < src1.array.length + src2.array.length due to the loop condition k < src1.array.length + src2.array.length由于循环条件
  • Therefore i + j < src1.array.length + src2.array.length因此i + j < src1.array.length + src2.array.length

If both i >= src1.array.length and j >= src2.array.length then i + j >= src1.array.length + src2.array.length , violating the facts above.如果i >= src1.array.lengthj >= src2.array.lengthi + j >= src1.array.length + src2.array.length违反了上述事实。

A couple other points and things to think about:其他几点和需要考虑的事情:

  • Be consistent with how you refer to data.与引用数据的方式保持一致。 If you have variables, use them.如果您有变量,请使用它们。 Either use numLength1 & numLength2 or use src1.length & src2.length .使用numLength1 & numLength2或使用src1.length & src2.length Either use myLength or use src1.array.length + src2.array.length .使用myLength或使用src1.array.length + src2.array.length
  • Should a merge method really output its own results, or should the code that called the method ( main ) handle all the input & output? merge方法真的应该 output 它自己的结果,还是调用该方法的代码 ( main ) 处理所有输入 & output?
  • Is the OrderedArray class safe to trust as "ordered", and is it doing its job properly, if you can directly access its internal data like src1.array and make modifications to the array? OrderedArray class 是否可以安全地信任为“已订购”,如果您可以直接访问其内部数据(如src1.array )并对数组进行修改,它是否正常工作?

The best way to merge two arrays without repetitive items in sorted order is that insert both of them into treeSet just like the following:合并两个没有重复项的 arrays 的最佳方法是将它们都插入到 treeSet 中,如下所示:

  public static int[] merge(int[] src1, int[] src2) {
        TreeSet<Integer> mergedArray= new TreeSet<>();
        for (int i = 0; i < src1.length; i++) {
            mergedArray.add(src1[i]);
        }
        for (int i = 0; i < src2.length; i++) {
            mergedArray.add(src2[i]);
        }
        return mergedArray.stream().mapToInt(e->(int)e).toArray();

    }

public static void main(String[] argh) {
    int[] src1 = {1,17,42,55};
    int[] src2 = {8,13,21,32,69};
Arrays.stream(merge(src1,src2)).forEach(s-> System.out.println(s));
  }

output: output:

1
8
13
17
21
32
42
55
69

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM