Сортировка двумерного массива по значениям более чем в одном столбце

Я хочу создать метод на 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 во второй позиции) ) и, наконец, 282 для тройки с 1 на второй позиции.

Любая помощь будет высоко оценен. Спасибо.


person Fco.Jav.Y    schedule 15.03.2020    source источник


Ответы (3)


Удалите параметр col из метода sortByColumn, поскольку на самом деле это не параметр, и измените метод следующим образом:

// 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 
person alainlompo    schedule 15.03.2020

Попробуйте так:

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)));
person vins    schedule 15.03.2020

Вы можете использовать цепочку компараторов для 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]

См. также: Как использовать вторичную алфавитную сортировку в строковом списке имен?

person Community    schedule 07.01.2021