# 将二维数组中每行的空元素移到该行的末尾

go评论69阅读模式

Move null elements of each row in a 2D array to the end of that row

# 问题

``````假设我有一个二维数组，看起来像这样：
``````

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

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 &lt; a.length; i++) {
for (int j = 0; j &lt; a.length; j++) {
if (a[i][j] != null) {
a[i][j] = b[i][j];
} else {
b[i][j] = a[i][j + 1];
}
}
}
``````

# 答案1

``````// Before
for (int j = 0; j < status.length; j++)

// Solution
for (int j = 0; j < status[i].length; j++)
``````
``````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++;
}
}
``````

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 &lt; status.length; j++)

// Solution
for (int j = 0; j &lt; 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 &lt; status[i].length; j++) {
// Move to the best compressed position
if (status[i][j] != null &amp;&amp; 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++;
}
}

``````

# 答案2

• 内部循环需要使用 `a[i].length`
• `a[i][j] = b[i][j];` 这里，你需要将 `a` 的值赋给 `b`
• 你需要为 `b` 的二维数组使用一个计数索引，每行一次，当发现非空值时，在存储后递增该索引，其余索引默认为 null。
``````for (int i = 0; i < a.length; i++) {
int indNew = 0; // 每行的索引
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] != null) {
b[i][indNew] = a[i][j]; // 存储非空值
indNew++;  // 存储后递增索引
}
}
}
``````

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 assign `a` value in `b`
• 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 &lt; a.length; i++) {
int indNew = 0; // Index for every row
for (int j = 0; j &lt; a[i].length; j++) {
if (a[i][j] != null) {
b[i][indNew] = a[i][j]; // store not null value
indNew++;  // increase after storing
}
}
}
``````

# 答案3

``````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)
// 过滤掉 null 元素
.filter(Objects::nonNull)
// 新数组，长度相同，null 放在最后
.toArray(q -> new String[row.length]))
.toArray(String[][]::new);
``````
``````// 输出
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
``````
``````[O, X, O, O, null, null, null]
[O, O, O, null, null, null, null]
``````

<sup>另请参阅：从旧的二维数组中删除 null，并将非 null 元素放入新的二维数组</sup>

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 = {
{&quot;O&quot;, &quot;X&quot;, null, &quot;O&quot;, &quot;O&quot;, null, null},
{null, null, &quot;O&quot;, null, null, &quot;O&quot;, &quot;O&quot;}};

String[][] arr2 = Arrays.stream(arr1)
.map(row -&gt; Arrays.stream(row)
// filter out null elements
.filter(Objects::nonNull)
// new array of the same length, nulls last
.toArray(q -&gt; 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]
``````

<sup>See also: Remove null from old 2d array and put the not null elements in a new 2d array</sup>

# 答案4

``````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]
``````

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 &lt;T&gt; void moveNulls(T[][] status) {
for (T[] row : status) {
if (null == row) {
continue;
}
int id = 0;
for (int i = 0; i &lt; row.length; i++) {
if (row[i] != null) {
row[id++] = row[i];
}
}
Arrays.fill(row, id, row.length, null);
}
}
``````

Test

``````String[][] status = {
{&quot;aaa&quot;, null, &quot;bbb&quot;, null, null, &quot;ccc&quot;},
{null, &quot;bbb&quot;, null, null, &quot;ccc&quot;, &quot;ddd&quot;, null, &quot;eee&quot;},
{null, null, &quot;fff&quot;, null, &quot;ccc&quot;, &quot;ddd&quot;, null, &quot;ggg&quot;, 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]
``````

• 本文由 发表于 2020年10月5日 22:39:52
• 转载请务必保留本文链接：https://go.coder-hub.com/64210824.html
• arrays
• java
• multidimensional-array
• null
• sorting

go 67

go 60

go 71

go 67