将2D数组中每行的null元素移动到该行的末尾



假设我有一个2d数组,如下所示:

[[O, X, null, O, O, null, null], [null, null, O, null, null, O, O]]

我希望它看起来像这样:

[[O, X, O, O, null, null, null], [O, O, O, null, null, null, null]]

我试过了,但不起作用:

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];
}
}
}

解决问题的一些要点

  • 您需要使用a[i].length进行内部循环
  • 这里的a[i][j] = b[i][j];需要在b中分配a
  • 您需要为b2D数组的每一行使用计数器索引,并且无论何时发现不为null,都会在存储后递增该索引,剩余的索引将被取消为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
}
}
}

首先让我印象深刻的是,您从不检查内部数组的长度。给定该示例,它将只检查前两个元素。

// Before
for (int j = 0; j < status.length; j++)
// Solution
for (int j = 0; j < status[i].length; j++)

至于具体的问题,你可以通过跟踪第一个null的索引并将你遇到的任何元素移动到它来完成

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++;
}
}

您可以在该数组上迭代,对于每一行filter,从null元素中取出,并收集剩余的相同长度的toArray,其中null最后一个:

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]

另请参阅:从旧的2d数组中删除null,并将非null元素放入新的2d数组

您不需要创建新的2D数组来存储其更新版本,null值可以简单地移动到每行的末尾,然后使用Arrays.fill从计算的索引开始设置null。

更新:该方法可以是通用的

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);
}
}

测试

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));
}

输出

[aaa, bbb, ccc, null, null, null]
[bbb, ccc, ddd, eee, null, null, null, null]
[fff, ccc, ddd, ggg, null, null, null, null, null]

最新更新