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

huangapple go评论82阅读模式
英文:

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

得分: 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

得分: 1

一些修复问题的要点:

  • 内部循环需要使用 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

得分: 1

你可以遍历这个数组,针对每一行使用 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)
                // 过滤掉 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

得分: 0

你无需创建新的二维数组来存储更新后的版本,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]
英文:

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]

huangapple
  • 本文由 发表于 2020年10月5日 22:39:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64210824.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定