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 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:
numLength1
& numLength2
or use src1.length
& src2.length
. Either use myLength
or use src1.array.length + src2.array.length
.merge
method really output its own results, or should the code that called the method ( main
) handle all the input & output? 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.