简体   繁体   中英

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. 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? 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:

1
8
13
17
21
32
42
55
69

and this is my current 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}. 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;

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:

  • 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 .

But depending on how comprehensively you test the code, you may then find you have a bigger problem: ArrayIndexOutOfBoundsException . Before trying to use any array index, such as src1.array[i] , you need to be sure it is valid. 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 . 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 } .

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:

  • k == i + j due to parity between k's incrementing and i & j's mutually exclusive incrementing
  • k < src1.array.length + src2.array.length due to the loop condition
  • Therefore 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.

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 . Either use myLength or use 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?
  • 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?

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:

  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:

1
8
13
17
21
32
42
55
69

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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