简体   繁体   English

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

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

I want to write a function that takes an 2d array and fills it with 1...n but counting the columns first instead of the rows:我想编写一个 function ,它采用一个二维数组并用1...n填充它,但首先计算列而不是行:

input = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};

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

if i were to loop through rows and then colums i get:如果我要遍历行然后列我得到:

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

How do I loop through colums first?我如何首先遍历列?

To iterate first over the columns of a jagged 2d array to fill it, you have to know the maximum number of columns beforehand, but if you don't know that, you can iterate to the Integer.MAX_VALUE and check at each step if the columns are still present or not:要首先迭代锯齿状二维数组的列来填充它,您必须事先知道最大列数,但如果您不知道,您可以迭代到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: Output:

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

See also: How do you rotate an array 90 degrees without using a storage array?另请参阅:如何在不使用存储阵列的情况下将阵列旋转 90 度?

To populate a 2d array first by columns, you can use two nested streams .要首先按列填充二维数组,可以使用两个嵌套 In case of a jagged 2d array , when you don't know beforehand the number of the columns in each row, in an outer stream you can traverse while the columns are still present.锯齿状二维数组的情况下,当您事先不知道每行中的列数时,在外部 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: Output:

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

See also: How to create a new List from merging 3 ArrayLists in round robin style?另请参阅:如何通过以循环方式合并 3 个 ArrayLists 来创建新列表?

You can do this by first transposing your input, executing your fill1 code and then transposing the output again.您可以通过首先转置您的输入、执行您的fill1代码然后再次转置 output 来做到这一点。
See this question for how to transpose a 2 dimensional array in Java: java multi-dimensional array transposing有关如何在 Java 中转置二维数组的信息,请参阅此问题: java 多维数组转置

If you were dealing with a regular 2d matrix, where all the rows had the same number of columns, the code would be a simple modification of the code for filling the matrix row-by-row:如果您正在处理一个常规 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++;
        }
    }
}

The process is basically the same for a ragged 2d array, but with a couple added twists:对于参差不齐的 2d 数组,该过程基本相同,但增加了一些变化:

  1. You need to do some extra work to figure out how many columns there could be (ie, the maximum row length)您需要做一些额外的工作来确定可能有多少列(即最大行长)
  2. You need to be prepared for the case when there's no cell at a given row/column position.您需要为给定行/列 position 中没有单元格的情况做好准备。

The following modification of the previous code addresses these issues:对前面代码的以下修改解决了这些问题:

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