问题描述
我想编写一个函数,它接受一个二维数组并用 1...n
填充它,但首先计算列而不是行:
input = {{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 中转置二维数组:java multi-dimensional array transposing
如果您处理的是常规二维矩阵,其中所有行的列数都相同,则代码将是对逐行填充矩阵的代码的简单修改:
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++;
}
}
}
对于参差不齐的二维数组,过程基本相同,但增加了一些曲折:
- 您需要做一些额外的工作来确定可能有多少列(即最大行长度)
- 您需要为给定的行/列位置没有单元格的情况做好准备。
对之前代码的以下修改解决了这些问题:
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++;
}
}
}
}
,
要先遍历锯齿状二维数组的列以填充它,您必须事先知道最大列数,但如果您不知道,可以迭代到 Integer.MAX_VALUE
并检查如果列仍然存在,则在每个步骤中:
int[][] arr = {{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]
另见:How do you rotate an array 90 degrees without using a storage array?
,要首先按列填充二维数组,您可以使用两个嵌套的流。在锯齿状二维数组的情况下,当您事先不知道每行中的列数时,您可以在列仍然存在的情况下遍历外部流。
/**
* @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}};
System.out.println("Max columns count: " + populate(arr));
System.out.println(Arrays.deepToString(arr));
}
输出:
Max columns count: 6
[[1,8,10,11,12],[2,6],[3],[4,9]]
另见:How to create a new List from merging 3 ArrayLists in round robin style?