Move null elements for each row in 2d array to the end of that row

落花浮王杯 提交于 2021-01-27 14:01:03

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!