Ciro Mertens
Ciro Mertens

Reputation: 113

Remove last element of each row of a 2D array

I have a 2 dimensional array where the rows differ in their lengths and I should write a method that makes it possible that the last x (that's to enter from the user) numbers from each row are taken away. E.g. matrix is:

{1 2 2}
{null}
{}
{1 3 2 3 3 7}
{1 2 4 5}

When the user enters 2 it should print:

{1}
{null}
{}
{1 3 2 3}
{1 2}

I don't know how I am able to do that. I thought if I introduce a new array I have to assign it a certain size as in 3 rows 4 columns for example. How can I even make a new 2D array with different long rows? The number of rows is easy it stays the same that's clear but the columns are the difficulty for me here.

I tried this but it doesn't work of course. I get an IndexOutOfBoundsException.

static int[][] cutAway(int[][] m, int cutAway) {
    if (m == null) return null;

    int[][] x = new int[m.length][m[0].length - cutAway];

    for (int row = 0; row < x.length; row++) {
        for (int col = 0; col < x[row].length; col++) {
            x[row][col] = m[row][col];

        }
    }
    return x;
}

Edit: I am not allowed to use these Arrays.copyOf things or something like that! So solutions with that don't really help.

Upvotes: 0

Views: 828

Answers (3)

Abhishek pruthvi V M
Abhishek pruthvi V M

Reputation: 156

The reason for Array Index out of bound is, when you subtract the cutAway the value becomes negative for 2nd row. Added a condition to check whether it's negative.

static int[][] cutAway(int[][] m, int cutAway) {
    if (m == null) return null;

    int[][] x = new int[m.length][];

    for (int row = 0; row < x.length; row++) {
        int size = m[row].length - cutAway;
        if (size < 0)
            size = 0;
        x[row] = new int[size];
        for (int col = 0; col < x[row].length; col++) {
            x[row][col] = m[row][col];
        }
    }
    return x;
}

Upvotes: 0

WJS
WJS

Reputation: 40057

int[][] arr = { { 1, 2, 2 }, null, {}, { 1, 3, 2, 3, 3, 7 },
        { 1, 2, 4, 5 } };
arr = cutAway(arr, 2);

for (int[] a : arr) {
    System.out.println(Arrays.toString(a));
}

prints

[1]
null
[]
[1, 3, 2, 3]
[1, 2]

The method

    
static int[][] cutAway(int[][] m, int cutAway) {
    if (m == null) {
        return null;
    }

    // create a return array with no rows assigned
    int[][] x = new int[m.length][];

    for (int row = 0; row < x.length; row++) {
        // get the source row for this run
        int[] source = m[row];
        // and assign it to x in case it can't be 
        // shortened
        x[row] = source;
        // now check its condition for null and length
        if (source != null && source.length > cutAway) {
            int[] dest = new int[source.length - cutAway];
            //looks good.  Assign to x
            x[row] = dest;
            // now do the copy using new rows length.
            for (int col = 0; col < dest.length; col++) {
                dest[col] = source[col];
            }
        }
    }
    return x;
}

Upvotes: 0

Seb34
Seb34

Reputation: 111

You can't allocate the rows before looping because they can have different sizes. This should work :

static int[][] cutAway(int[][] array, int cutAway) {
  if ((array == null) || (array.length == 0)) {
    return array;
  }

  int[][] res = new int[array.length][];
  for (int row = 0; row < array.length; row++) {
    res[row] = Arrays.copyOfRange(array[row], 0, Math.max(array[row].length - cutAway, 0));
  }
  return res;
}

Upvotes: 2

Related Questions