1

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:

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?

Community
  • 1
  • 1

4 Answers4

0

You can do this by first transposing your input, executing your fill1 code and then transposing the output again.
See this question for how to transpose a 2 dimensional array in Java: java multi-dimensional array transposing

miva2
  • 2,111
  • 25
  • 34
0

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:

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:

  1. You need to do some extra work to figure out how many columns there could be (i.e., the maximum row length)
  2. You need to be prepared for the case when there's no cell at a given row/column 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++;
            }
        }
    }
}
Kevin Anderson
  • 4,568
  • 3
  • 13
  • 21
0

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:

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]

See also: How do you rotate an array 90 degrees without using a storage array?

0

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.

/**
 * @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]]

See also: How to create a new List from merging 3 ArrayLists in round robin style?