按升序对整个二维数组进行排序

时间:2021-02-20 10:00:16

标签: java arrays sorting multidimensional-array

我想使用 Arrays.sort() 按升序对二维数组进行排序。

例如,我有这个数组:

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

排序后,输出应该是:

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

像这样编写代码,但它按行排序:

package domain;

import java.util.Arrays;

public class Exercise {
    private int[][] matrix = {
            {34, 2, 15, 12, 56},
            {3, 67, 6, 21, 9},
            {22, 5, 18, 65, 10},
            {52, 36, 112, 90, 0},
            {19, 48, 73, 16, 88}};

    // Method that displays the array
    public void DisplayArray() {
        for (int[] row : matrix) {
            System.out.println(Arrays.toString(row));
        }
    }

    public void Sorting() {
        for (int[] row : matrix) {
            Arrays.sort(row);
        }
    }
}

4 个答案:

答案 0 :(得分:2)

使用流,可以将二维数组转换为整数流,然后将其重新收集为二维数组:

public static int[][] sort2D(int[][] arr) {
    int rows = arr.length;
    int cols = arr[0].length;
    int[] row = {0};
    
    return Arrays.stream(arr)
                 .flatMapToInt(Arrays::stream)
                 .sorted()
                 .boxed()
                 .collect(Collectors.groupingBy(x -> row[0]++ / cols))
                 .values()
                 .stream()
                 .map(r -> r.stream().mapToInt(Integer::intValue).toArray())
                 .toArray(int[][]::new);
}

测试

int[][] arr = {
  {9, 7, 5, 4},
  {3, 12, 11, 8},
  {6, 1, 2, 10}
};
int[][] sorted = sort2D(arr);
Arrays.stream(sorted)
      .map(Arrays::toString)
      .forEach(System.out::println);

输出

[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]

更新
使用方法 Stream::collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner):

可以实现更简单的解决方案
public static int[][] sort2D(int[][] arr) {
    int rows = arr.length;
    int cols = arr[0].length;
    AtomicInteger ix = new AtomicInteger(0); // int[] ix = {0}; can be used too
    
    return Arrays
        .stream(arr)
        .flatMapToInt(Arrays::stream)
        .sorted()
        .collect(
            () -> new int[rows][cols], // supplier creating the result array
            (a, x) -> a[ix.get() / cols][ix.getAndIncrement() % cols] = x, // populate with sorted data
            (arr1, arr2) -> {} // nothing to combine
        );
}

答案 1 :(得分:0)

问题可以分为三个部分。

  1. 将每行大小为 n 的所有元素放入一个向量中
  2. 对该向量进行排序
  3. 将其分解为大小为 n 的向量

使用您的示例输入

int[][] arr = { {3,8,5},{1,6,7},{2,4,9} };

和方法:

int[][] sorted(int[][] in) {
    int[] all = new int[in.length * in.length]; // assumption: square matrix
    int i = 0;
    for (int[] row : in) {
        for (int el : row) {
            all[i] = el;
            i++;
        }
    }
    Arrays.sort(all); // sort all elements in single vector
    // put sorted elements in your "output" array
    int[][] out = new int[in.length][in.length];
    int row = 0;
    int col = 0;
    for (int el : all) {
        // note col,row and not row,col!
        out[col][row] = el;
        row++;
        if (row == in.length) {
            row = 0;
            col++;
        }
    }
    return out;
}

你有

int[][] sorted = sorted(arr);

答案 2 :(得分:0)

你可以试试这个。在这里得到了我的参考java Arrays.sort 2d array

Arrays.sort(matrix, (a, b) -> a[0] - b[0]);

答案 3 :(得分:0)

您可以先将这个二维数组展平为一维,然后使用 Arrays.sort 方法对一个平面数组进行排序,然后用排序后的平面数组中的元素组装回一个相同维度的二维数组:

// original array
int[][] arr = {
        {3, 8, 5},
        {1, 6, 7},
        {2, 4, 9}};
// flatten a 2d array
int[] flatArr = Arrays.stream(arr).flatMapToInt(Arrays::stream).toArray();

// sorting
Arrays.sort(flatArr);
// reassemble a 2d array of the same dimensions from a flat array
AtomicInteger flatIndex = new AtomicInteger(0);
// iterate over the rows and their elements of
// the original array and sequentially fill the
// new array with elements from the flat array
int[][] sorted = Arrays.stream(arr)
        .map(row -> Arrays.stream(row)
                .map(j -> flatArr[flatIndex.getAndAdd(1)])
                .toArray())
        .toArray(int[][]::new);
// output
Arrays.stream(sorted).map(Arrays::toString).forEach(System.out::println);
//[1,2,3]
//[4,5,6]
//[7,8,9]

另见:
How do you rotate an array 90 degrees without using a storage array?
Filling a jagged 2d array first by columns