问题
Let's say I have a 2d array which looks like this:
[[O, X, null, O, O, null, null], [null, null, O, null, null, O, O]]
And I want it to look like this:
[[O, X, O, O, null, null, null], [O, O, O, null, null, null, null]]
I tried this, but it's not working:
String[][] a = new String[row][col];
String[][] b = new String[row][col];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i][j] != null) {
a[i][j] = b[i][j];
} else {
b[i][j] = a[i][j + 1];
}
}
}
回答1:
Some points to fix the problem
- You need to use
a[i].length
for inner loop a[i][j] = b[i][j];
here you need to assigna
value inb
- You need to use a counter index for
b
2D array's every row and whenever found not-null increment this after storing and remaining index are by defult null.
for (int i = 0; i < a.length; i++) {
int indNew = 0; // Index for every row
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] != null) {
b[i][indNew] = a[i][j]; // store not null value
indNew++; // increase after storing
}
}
}
回答2:
The first thing that stands out to me is you never check the length of the inner array. Given the example, it will only ever check the first 2 elements.
// Before
for (int j = 0; j < status.length; j++)
// Solution
for (int j = 0; j < status[i].length; j++)
As for the specific problem, you could do it by keeping track of the index of the first null and moving any elements you encounter to it.
int lastEmpty = 0;
for (int j = 0; j < status[i].length; j++) {
// Move to the best compressed position
if (status[i][j] != null && status[i][lastEmpty] == null) {
status[i][lastEmpty] = status[i][j];
status[i][j] = null;
}
// Shift to always be the first null
if (status[i][lastEmpty] != null) {
lastEmpty++;
}
}
回答3:
You do not need to create new 2D array to store its updated version, null
values can be simply moved to the end of each row and then use Arrays.fill
to set null starting from the calculated index.
update: the method can be generic
public static <T> void moveNulls(T[][] status) {
for (T[] row : status) {
if (null == row) {
continue;
}
int id = 0;
for (int i = 0; i < row.length; i++) {
if (row[i] != null) {
row[id++] = row[i];
}
}
Arrays.fill(row, id, row.length, null);
}
}
Test
String[][] status = {
{"aaa", null, "bbb", null, null, "ccc"},
{null, "bbb", null, null, "ccc", "ddd", null, "eee"},
{null, null, "fff", null, "ccc", "ddd", null, "ggg", null},
};
moveNulls(status);
for (String[] row : status) {
System.out.println(Arrays.toString(row));
}
Output
[aaa, bbb, ccc, null, null, null]
[bbb, ccc, ddd, eee, null, null, null, null]
[fff, ccc, ddd, ggg, null, null, null, null, null]
回答4:
You can iterate over this array and for each row filter out the null elements and collect the remaining ones toArray of the same length where the nulls go last:
String[][] arr1 = {
{"O", "X", null, "O", "O", null, null},
{null, null, "O", null, null, "O", "O"}};
String[][] arr2 = Arrays.stream(arr1)
.map(row -> Arrays.stream(row)
// filter out null elements
.filter(Objects::nonNull)
// new array of the same length, nulls last
.toArray(q -> new String[row.length]))
.toArray(String[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
[O, X, O, O, null, null, null]
[O, O, O, null, null, null, null]
See also: Remove null from old 2d array and put the not null elements in a new 2d array
来源:https://stackoverflow.com/questions/64210824/move-null-elements-for-each-row-in-2d-array-to-the-end-of-that-row