对一个二维数组按照多列的值进行排序。

huangapple go评论80阅读模式
英文:

Sorting a 2d array by values in more than one column

问题

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 if (entry1[col] > entry2[col])
                    return -1;
                else
                    return Integer.compare(entry1[2], entry2[2]);
            }
        }); // 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 2nd Column
        int col = 1;  // Change to 1 for 2nd column
        sortByColumn(matrix, col);

        // 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();
        }
    }
}
英文:

I want to build a method in Java for sorting an array according to values in more than a given column. Let me explain that with an example (matrix array):

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

I need to sort every triplet according to the second position in decreasing order. After that, I need to sort the triplet in increasing order according to the third position.

The code that I'm using for that is:

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&lt;int[]&gt;() {
            @Override
            // Compare values according to columns
            public int compare(final int[] entry1,
                               final int[] entry2) {

                if (entry1[col] &lt; 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 &lt; matrix.length; i++) {
            for (int j = 0; j &lt; matrix[i].length; j++)
                System.out.print(matrix[i][j] + &quot; &quot;);
            System.out.println();
        }
    }
}

The output of the previously described code is:

[[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]]

But the output needed must be:

[[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]]

Please note that according to the second position we have the following: 5,5,5,4,3,2,2,2,2,1 (decreasing order) and according to the third position the order is: 134,171,293 (for the triplets with a "5" in the second position), 191 (for the triplet with a "4" in the second position), 354 (for the triplet with a "3" in the second position), 432,456,475,491 (for the triplets with a "2" in the second position) and finally 282 for the triplet with a "1" in the second position.

Any help would be highly appreciated. Thanks.

答案1

得分: 0

尝试这种方式:

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)));
英文:

Try this way:

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&lt;int[]&gt; secondDecrease = (a, b) -&gt; b[1] - a[1];
Comparator&lt;int[]&gt; thirdIncrease = (a, b) -&gt; a[2] - b[2];

Arrays.stream(matrix)
        .sorted(secondDecrease.thenComparing(thirdIncrease))
        .forEach(s -&gt; System.out.println(Arrays.toString(s)));

答案2

得分: 0

// 从sortByColumn方法中删除col参数,因为它实际上不是一个参数,并按以下方式更改该方法:
// 函数,按列排序
public static void sortbyColumn(int arr[][]) {
    // 使用内置排序函数Arrays.sort
    Arrays.sort(arr, new Comparator<int[]>() {
        @Override
        // 根据列比较值
        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]));
        }
    }); // 结束函数调用sort()。
}

当然,将主函数中的调用更改为 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
英文:

Remove the col parameter from the sortByColumn method since it is not really a parameter and change the method in this way:

// Function to sort by column 
public static void sortbyColumn(int arr[][]) {
    // Using built-in sort function Arrays.sort 
    Arrays.sort(arr, new Comparator&lt;int[]&gt;() {
        @Override
        // Compare values according to columns 
        public int compare(final int[] entry1, final int[] entry2) {
            if (entry1[1] &lt; entry2[1])
                return 1;
            else if (entry1[1] &gt; entry2[1])
                return -1;

            return -1 * Integer.valueOf(entry2[2])
                    .compareTo(Integer.valueOf(entry1[2]));
        }
    }); // End of function call sort(). 
}

Of course change the call in main to sortbyColumn(matrix);

Explanation:

We need to compare by the third column only in cases of equality by the second column (which means thet first comparison numeric result is equal to 0). In that case we compare in reverse order, which we can obtain by multiplying the comparison result by -1.

Result:

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 

答案3

得分: 0

你可以使用比较器链来首先按照指定顺序对一列进行排序,然后按照不同顺序对另一列进行排序:

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}};
// 按照第二列降序排序,
// 然后按照第三列升序排序
Arrays.sort(matrix, Comparator
        // &lt;int[] - 对象类型, Integer - 返回类型&gt;
        .&lt;int[], Integer&gt;comparing(arr -&gt; arr[1], Comparator.reverseOrder())
        .thenComparing(arr -&gt; arr[2], Comparator.naturalOrder()));
// 输出
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]

<sup>另请参阅:如何在字符串名称列表上使用辅助字母排序?</sup>

英文:

You can use the comparator chaining to sort first by one column in the specified order and then by another column in a different order:

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
        // &lt;int[] - object type, Integer - return type&gt;
        .&lt;int[], Integer&gt;comparing(arr -&gt; arr[1], Comparator.reverseOrder())
        .thenComparing(arr -&gt; 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]

<sup>See also: How to use a secondary alphabetical sort on a string list of names?</sup>

huangapple
  • 本文由 发表于 2020年3月15日 10:09:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/60689084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定