繁体   English   中英

首先按列填充锯齿状二维数组

[英]Filling a jagged 2d array first by columns

我想编写一个 function ,它采用一个二维数组并用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++;
        }
    }
}

我如何首先遍历列?

要首先迭代锯齿状二维数组的列来填充它,您必须事先知道最大列数,但如果您不知道,您可以迭代到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));
}

Output:

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

另请参阅:如何在不使用存储阵列的情况下将阵列旋转 90 度?

要首先按列填充二维数组,可以使用两个嵌套 锯齿状二维数组的情况下,当您事先不知道每行中的列数时,在外部 stream 中,您可以在列仍然存在时进行遍历。

/**
 * @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));
}

Output:

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

另请参阅:如何通过以循环方式合并 3 个 ArrayLists 来创建新列表?

您可以通过首先转置您的输入、执行您的fill1代码然后再次转置 output 来做到这一点。
有关如何在 Java 中转置二维数组的信息,请参阅此问题: 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. 您需要为给定行/列 position 中没有单元格的情况做好准备。

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

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

暂无
暂无

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

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