【问题标题】:Sorting a 2d array by values in more than one column按多列中的值对二维数组进行排序
【发布时间】:2020-06-26 13:38:56
【问题描述】:

我想在 Java 中构建一个方法,用于根据多个给定列中的值对数组进行排序。让我用一个例子(矩阵数组)来解释一下:

int matrix[][] = {
        {0,2,432},{1,1,282},{2,2,456},{3,4,191},{4,5,293},
        {5,2,475},{6,2,491},{7,5,171},{8,5,134},{9,3,354}};

我需要根据第二个位置以降序对每个三元组进行排序。之后,我需要根据第三个位置对三元组进行升序排序。

我使用的代码是:

import java.util.*;

public class sort2DMatrixByColumn {
    // Function to sort by column
    public static void sortByColumn(int arr[][], int col) {
        // Using built-in sort function Arrays.sort
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            // Compare values according to columns
            public int compare(final int[] entry1,
                               final int[] entry2) {

                if (entry1[col] < entry2[col])
                    return 1;
                else
                    return -1;
            }
        }); // End of function call sort().
    }

    // Driver Code
    public static void main(String args[]) {
        int matrix[][] = {
                {0,2,432},{1,1,282},{2,2,456},{3,4,191},{4,5,293},
                {5,2,475},{6,2,491},{7,5,171},{8,5,134},{9,3,354}};

        // Sort this matrix by 2rd Column
        int col = 2;
        sortByColumn(matrix, col - 1);

        // Display the sorted Matrix
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++)
                System.out.print(matrix[i][j] + " ");
            System.out.println();
        }
    }
}

前面描述的代码的输出是:

[[8,5,134],[7,5,171],[4,5,293],[3,4,191],[9,3,354],
 [6,2,491],[5,2,475],[2,2,456],[0,2,432],[1,1,282]]

但需要的输出必须是:

[[8,5,134],[7,5,171],[4,5,293],[3,4,191],[9,3,354],
 [0,2,432],[2,2,456],[5,2,475],[6,2,491],[1,1,282]]

请注意,根据第二个位置,我们有以下:5,5,5,4,3,2,2,2,2,1(递减顺序),根据第三个位置,顺序是:134,171,293 (对于第二个位置带有“5”的三连音),191(对于第二个位置带有“4”的三连音),354(对于第二个位置带有“3”的三连音),432,456,475,491(对于在第二个位置带有“2”的三连音),最后是在第二个位置带有“1”的三连音的 282。

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: java arrays sorting multidimensional-array columnsorting


    【解决方案1】:

    从 sortByColumn 方法中删除 col 参数,因为它不是真正的参数,并以这种方式更改方法:

    // Function to sort by column 
    public static void sortbyColumn(int arr[][]) {
        // Using built-in sort function Arrays.sort 
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            // Compare values according to columns 
            public int compare(final int[] entry1, final int[] entry2) {
                if (entry1[1] < entry2[1])
                    return 1;
                else if (entry1[1] > entry2[1])
                    return -1;
    
                return -1 * Integer.valueOf(entry2[2])
                        .compareTo(Integer.valueOf(entry1[2]));
            }
        }); // End of function call sort(). 
    }
    

    当然把main中的调用改成sortbyColumn(matrix);

    解释:

    只有在第二列相等的情况下,我们才需要通过第三列进行比较(这意味着第一个比较数字结果等于 0)。在这种情况下,我们以相反的顺序进行比较,我们可以将比较结果乘以-1

    结果:

    8 5 134 
    7 5 171 
    4 5 293 
    3 4 191 
    9 3 354 
    0 2 432 
    2 2 456 
    5 2 475 
    6 2 491 
    1 1 282 
    

    【讨论】:

      【解决方案2】:

      试试这个方法:

      int matrix[][] = {
              {0, 2, 432}, {1, 1, 282}, {2, 2, 456}, {3, 4, 191}, {4, 5, 293},
              {5, 2, 475}, {6, 2, 491}, {7, 5, 171}, {8, 5, 134}, {9, 3, 354}};
      
      Comparator<int[]> secondDecrease = (a, b) -> b[1] - a[1];
      Comparator<int[]> thirdIncrease = (a, b) -> a[2] - b[2];
      
      Arrays.stream(matrix)
              .sorted(secondDecrease.thenComparing(thirdIncrease))
              .forEach(s -> System.out.println(Arrays.toString(s)));
      

      【讨论】:

        【解决方案3】:

        您可以使用 比较器链接sort 首先按指定顺序按一列,然后按不同顺序按另一列:

        int[][] matrix = {
                {0, 2, 432}, {1, 1, 282}, {2, 2, 456}, {3, 4, 191}, {4, 5, 293},
                {5, 2, 475}, {6, 2, 491}, {7, 5, 171}, {8, 5, 134}, {9, 3, 354}};
        
        // sorting by second column in descending order,
        // then by third column in ascending order
        Arrays.sort(matrix, Comparator
                // <int[] - object type, Integer - return type>
                .<int[], Integer>comparing(arr -> arr[1], Comparator.reverseOrder())
                .thenComparing(arr -> arr[2], Comparator.naturalOrder()));
        
        // output
        Arrays.stream(matrix).map(Arrays::toString).forEach(System.out::println);
        
        [8, 5, 134]
        [7, 5, 171]
        [4, 5, 293]
        [3, 4, 191]
        [9, 3, 354]
        [0, 2, 432]
        [2, 2, 456]
        [5, 2, 475]
        [6, 2, 491]
        [1, 1, 282]
        

        另见:How to use a secondary alphabetical sort on a string list of names?

        【讨论】:

          猜你喜欢
          • 2023-03-26
          • 2011-07-15
          • 2022-11-25
          • 2013-04-12
          • 2013-08-17
          • 2022-01-01
          • 2011-10-25
          • 1970-01-01
          相关资源
          最近更新 更多