【问题标题】:Sort matrix row-wise and keep indices按行排序矩阵并保留索引
【发布时间】:2021-08-06 01:04:46
【问题描述】:

我正在尝试在 Java 中按行对二维数组进行排序。但是,我只想对索引进行排序,而不是对值本身进行排序。

例如:

values
1.3 0.3 0.4 0.1
0.4 0.2 3.7 2.4
2.1 6.4 1.9 0.3

indices       sorted according to values
0 1 2 3       3 1 2 0
0 1 2 3  -->  1 0 3 2
0 1 2 3       3 2 0 1

不幸的是,我在其他 StackOverflow 问题中可以找到的任何内容要么是如何对矩阵进行排序,要么是在对数组进行排序时如何保留索引。但有效地结合两者是我努力的方向。

任何见解都将不胜感激。

到目前为止,我尝试了什么,但这不起作用。它似乎根本没有改变我的矩阵。

// Function to sort the given matrix in row wise manner
public void RowWiseSort(Integer[][] idx, double[][] values) {
    // Traverse the row
    for (int i = 0; i < (int) idx.length; i++) {
        ArrayIndexComparator comp = new ArrayIndexComparator(values[i]);

        // Row - Wise Sorting
        Arrays.sort(idx[i], comp);
    }
}

private class ArrayIndexComparator implements Comparator<Integer> {
    private final double[] A;

    public ArrayIndexComparator(double[] arr) {
        this.A = arr;
    }

    @Override
    public int compare(Integer o1, Integer o2) {
        return Double.compare(A[o1], A[o2]);
    }
}

【问题讨论】:

    标签: java arrays sorting matrix multidimensional-array


    【解决方案1】:

    鉴于您的示例 2D-Array of doubles

    double[][] values = {
            {1.3, 0.3, 0.4, 0.1},
            {0.4, 0.2, 3.7, 2.4},
            {2.1, 6.4, 1.9, 0.3}};
    

    并且预期结果是根据上述值排序的索引(整数)的二维数组;你可以这样做:

    Integer[][] result = IntStream.range(0, values.length)
            .mapToObj(i -> IntStream.range(0, values[i].length)
                    .boxed()
                    .sorted(Comparator.comparingDouble(j -> values[i][j]))
                    .toArray(Integer[]::new))
            .toArray(Integer[][]::new);
    
    for (Integer[] row : result) {
        System.out.println(Arrays.toString(row));
    }
    

    输出:

    [3, 1, 2, 0]
    [1, 0, 3, 2]
    [3, 2, 0, 1]
    

    【讨论】:

      【解决方案2】:

      您可以按如下方式使用Java Streams:

      double[][] arr = {
              {1.3, 0.3, 0.4, 0.1},
              {0.4, 0.2, 3.7, 2.4},
              {2.1, 6.4, 1.9, 0.3}};
      
      // row-wise sorted array of indices
      int[][] idx = Arrays.stream(arr)
              .map(row -> IntStream
                      .range(0, row.length)
                      // Stream<Integer>
                      .boxed()
                      // sort indices by element value
                      .sorted(Comparator.comparingDouble(i -> row[i]))
                      // IntStream
                      .mapToInt(Integer::intValue)
                      // row of indices
                      .toArray())
              .toArray(int[][]::new);
      
      Arrays.stream(idx).map(Arrays::toString).forEach(System.out::println);
      //[3, 1, 2, 0]
      //[1, 0, 3, 2]
      //[3, 2, 0, 1]
      

      另见:Finding the position of a row element in a 2d ordered array

      【讨论】:

        【解决方案3】:

        您可以创建自定义数据结构,例如“MatrixEntry”可以封装价值和指数。 您可以为 MatrixEntry 的实例定义自定义比较逻辑。您可以使用 MatrixEntry 实例的 2D 数组,而不是 2D 数组。然后,您可以根据您定义的自定义比较逻辑对行进行排序。

        class MatrixEntry implements Comparable<MatrixEntry> {
            double value;
            int indiceInRow;
        
            @Override
            public int compareTo(MatrixEntry other) {
                // define your comparing logic.
            }
        }
        

        对所有条目进行排序后,您可以轻松地从二维矩阵条目数组生成一个二维索引数组。

        【讨论】:

          猜你喜欢
          • 2018-04-29
          • 2019-05-31
          • 1970-01-01
          • 2021-06-29
          • 1970-01-01
          • 2017-08-11
          • 2019-05-13
          • 2021-12-01
          • 2017-05-24
          相关资源
          最近更新 更多