Reputation: 113
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
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
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
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