繁体   English   中英

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

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

对我来说突出的第一件事是你从不检查内部数组的长度。 给出这个例子,它只会检查前 2 个元素。

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

解决问题的一些要点

  • 您需要使用a[i].length进行内循环
  • a[i][j] = b[i][j]; 在这里你需要在b分配a
  • 您需要为b 2D 数组的每一行使用计数器索引,并且在存储后发现非空增量时,剩余索引默认为空。
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
    }
  }
}

你可以遍历这个数组,并为每一行filternull元素,并且收集剩余的toArray相同的长度,其中走过去的:

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]

另请参阅:从旧的二维数组中删除空值并将非空元素放入新的二维数组中

您不需要创建新的二维数组来存储其更新版本,只需将null值移动到每一行的末尾,然后使用Arrays.fill从计算的索引开始设置空值。

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

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM