【问题标题】:Sorting through entire 2D array in ascending order按升序对整个二维数组进行排序
【发布时间】:2021-05-23 04:38:28
【问题描述】:

我想使用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);
        }
    }
}

【问题讨论】:

    标签: java arrays sorting multidimensional-array


    【解决方案1】:

    这个问题可以分为三个部分。

    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】:

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

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

      【讨论】:

      • 确实,最简单的方法就是将尺寸拉平
      【解决方案3】:

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

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

      【讨论】:

      • 这只是按行的第一个元素对行进行排序,甚至没有对每一行进行排序。
      【解决方案4】:

      您可以先将这个二维数组展平为一维,然后使用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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-03
        • 2013-08-17
        • 2021-04-11
        • 1970-01-01
        • 2020-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多