先按列填充锯齿形2d数组



我想写一个函数,它需要一个2d数组,并填充它与1...n,但计数列第一,而不是行:

input = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
the output should be: {{1, 5, 7, 8}, {2}, {3}, {4, 6}};

如果我先循环行,然后循环列,我得到:

private static void fill1(int[][] input) {
int count = 1;
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[i].length; j++) {
input[i][j] = count;
count++;
}
}
}

如何先遍历列?

您可以通过首先转换输入,执行fill1代码,然后再次转换输出来做到这一点。
如何在Java中对二维数组进行转置,请参见这个问题:

如果您正在处理一个常规的2d矩阵,其中所有的行都具有相同的列数,那么代码将是对代码的简单修改,用于逐行填充矩阵:

private static void fill1(int[][] input) {
int count = 1;
for (int j = 0; j < input[0].length; j++) {
for (int i = 0; i < input.length; i++) {
input[i][j]= count;
count++;
}
}
}

对于粗糙的2d数组,这个过程基本上是相同的,但是增加了一些变化:

  1. 你需要做一些额外的工作来弄清楚可能有多少列(即,最大行长度)
  2. 您需要为在给定的行/列位置没有单元格的情况做好准备。

对前面代码的以下修改解决了这些问题:

private static void fill1(int[][] input) {
int maxCols = input[0].length;
for (int i = 1; i < input.length; ++i) {
if (input[i].length > maxCols) {
maxCols = input[i].length;
}
}
int count = 1;
for (int j = 0; j < maxCols; j++) {
for (int i = 0; i < input.length; i++) {
if (j < input[i].length) {
input[i][j]= count;
count++;
}
}
}
}

要先遍历锯齿形2d数组的列来填充它,你必须事先知道最大列数,但如果你不知道,你可以迭代到Integer.MAX_VALUE并在每一步检查列是否仍然存在:

int[][] arr = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
int count = 1;
for (int col = 0; col < Integer.MAX_VALUE; col++) {
boolean max = true;
for (int row = 0; row < arr.length; row++) {
if (col < arr[row].length) {
arr[row][col] = count;
count++;
max = false;
}
}
if (max) break;
}
for (int[] row : arr) {
System.out.println(Arrays.toString(row));
}

输出:

[1, 5, 7, 8]
[2]
[3]
[4, 6]

参见:如何在不使用存储阵列的情况下旋转数组90度?

要首先按列填充2d数组,您可以使用两个嵌套的。对于一个锯齿2d数组,当您事先不知道每行中的列数时,可以在列仍然存在的情况下在外部流中遍历。

/**
* @param arr array that should be populated.
* @return maximum row length, i.e. columns count.
*/
private static long populate(int[][] arr) {
AtomicInteger counter = new AtomicInteger(1);
return IntStream
// traverse through the array columns
.iterate(0, i -> i + 1)
// process the array rows where
// this column is present
.mapToLong(i -> Arrays.stream(arr)
// filter those rows where
// this column is present
.filter(row -> row.length > i)
// assign a value to the element and increase the counter
.peek(row -> row[i] = counter.getAndIncrement())
// count of rows where this column is present
.count())
// while the columns are still present
.takeWhile(i -> i > 0)
// max columns count
.count();
}
public static void main(String[] args) {
int[][] arr = {{0, 0, 0, 0, 0, 0}, {0, 0}, {0}, {0, 0, 0}};
System.out.println("Max columns count: " + populate(arr));
System.out.println(Arrays.deepToString(arr));
}

输出:

Max columns count: 6
[[1, 5, 8, 10, 11, 12], [2, 6], [3], [4, 7, 9]]

参见:如何创建一个新的列表从合并3个数组列表在轮询风格?

最新更新