0

Here is my method to merge two sorted arrays:

public static int[] AddString(int[] a, int[] b, int pos, int n){

    if(n > 1){
        if(a[0] > b[0] && !(a.length == 0)){
            c[pos] = b[0];
            b = Arrays.copyOfRange(b, 1, b.length);
        }else{
            c[pos] = a[0];
            a = Arrays.copyOfRange(a, 1, a.length);
        }
        AddString(a, b, pos + 1, n - 1);
    }
    return c;
}

I need to combine two sorted arrays. These are the arrays:

static int[] c = new int[String1.length + String2.length];
static int[] array1 = new int[]{2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
static int[] array2 = new int[]{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};

Line used to invoke AddString:

System.out.println(Arrays.toString(AddString(String1, String2, 0, n)));

Now my application returns this error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at com.company.Main.AddString(Main.java:21)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.AddString(Main.java:28)
at com.company.Main.main(Main.java:14)

I understand this is because my application is working with a non existant array index but I don't understand where this happens. The problem occurs when array1 is empty. Could anyone help me?

phflack
  • 2,729
  • 1
  • 9
  • 21

1 Answers1

3

a[0] > b[0] && !(a.length == 0) is causing the out of bounds exception

Looking into it, you're first accessing a[0], then b[0] before checking any length values

Instead you may want a.length > 0 && b.length > 0 && a[0] > b[0]

Note that java supports short circuiting: Java logical operator short-circuiting


After deciphering what exactly you're trying to do, you're fairly close to accomplishing it

Here's a few different ways to merge the two sorted arrays

1.

Your implementation fixed up a bit, recursive

public static int[] merge(int[] a, int[] b, int pos, int n)
{
    if(n > 1) //expecting a or b to have an element
        if(a.length > 0)
            if(b.length > 0)
                if(a[0] > b[0]) //a and b have elements
                {
                    c[pos] = b[0];
                    b = Arrays.copyOfRange(b, 1, b.length);
                }
                else
                {
                    c[pos] = a[0];
                    a = Arrays.copyOfRange(a, 1, a.length);
                }
            else //b has no elements, a does
            {
                c[pos] = a[0];
                a = Arrays.copyOfRange(a, 1, a.length);
            }
        else //a has no elements
            if(b.length > 0)
            {
                c[pos] = b[0];
                b = Arrays.copyOfRange(b, 1, b.length);
            }

        merge(a, b, pos + 1, n - 1);
    }

    return c;
}

2.

Also recursive

int[] merge(int[] a, int[] b)
{
    return merge(a, 0, b, 0, new int[a.length + b.length], 0);
}

int[] merge(int[] a, int aCounter, int[] b, int bCounter, int[] out, int outCounter)
{
    if(aCounter < a.length && bCounter < b.length) //both arrays have elements
        if(a[aCounter] < b[bCounter])
        {
            out[outCounter] = a[aCounter];
            return merge(a, aCounter + 1, b, bCounter, out, outCounter + 1);
        }
        else
        {
            out[outCounter] = b[bCounter];
            return merge(a, aCounter, b, bCounter + 1, out, outCounter + 1);
        }

    if(aCounter < a.length) //only a has elements
    {
        out[outCounter] = a[aCounter];
        return merge(a, aCounter + 1, b, bCounter, out, outCounter + 1);
    }

    if(bCounter < b.length) //only b has elements
    {
        out[outCounter] = b[bCounter];
        return merge(a, aCounter, b, bCounter + 1, out, outCounter + 1);
    }

    //no more elements
    return out;
}

3.

Non-recursive

int[] merge(int[] a, int[] b)
{
    int[] out = new int[a.length + b.length]; //out array large enough for both contents
    int ac = 0; //a index counter
    int bc = 0; //b index counter
    int outc = 0; //out index counter

    //merge until one array is fully used up
    while(ac < a.length && bc < b.length)
        out[outc++] = a[ac] < b[bc] ? a[ac++] : b[bc++];

    //add the remaining elements to out
    while(ac < a.length)
        out[outc++] = a[ac++];
    while(bc < b.length)
        out[outc++] = b[bc++];

    //return the merged array
    return out;
}
phflack
  • 2,729
  • 1
  • 9
  • 21
  • Thanks for the reply, I get what you mean but when I use that code I still get the same error message. –  Oct 24 '17 at 18:27
  • @Mike same error at the same line? Or are you getting out of bounds on another line? You may want to also look at `c[pos]` and maybe add `if(pos < c.length)` or similar. Also note that you potentially call `a[0]` in the else block, which may have been caused by `a` being empty – phflack Oct 24 '17 at 18:30
  • You were right, I added the if conditions to the else statement and the error is gone, my array is now filled with 0's though... –  Oct 24 '17 at 18:37
  • @Mike int arrays are initialized with 0s, are you sure your logic is correct? What is it that you are trying to do? – phflack Oct 24 '17 at 18:39
  • I'm not sure it is correct, I'm still a beginner. I try to add two sorted arrays into a third new array for a class about recursion in algorithms. –  Oct 24 '17 at 18:45
  • @Mike I have added a few different algorithms for merging – phflack Oct 24 '17 at 19:20