【问题标题】:Finding indexes of 2d array elements in a sorted 2d array by columns按列查找已排序二维数组中二维数组元素的索引
【发布时间】:2021-02-03 22:37:29
【问题描述】:

我有两个相同维度的二维整数数组需要比较。我将通过一个示例解释我需要什么,其中 Sjm1 是“原始”数组,而 Sjm2 数组具有与 Sjm1 相同的值,但每列的值按升序排列(即“0”是Sjm1 在第 0 列中,所以 Sjm2[0][0]=0;然后“70”是第 0 列中 Sjm1 的下一个最小值⇒Sjm2[1][0]=70;等等)。我有一种方法可以将“Sjm1”数组排序为“Sjm2”。

现在我需要构建一个“输出”数组(整数的二维数组),其中每列中的值表示 Sjm1 数组中与 Sjm2 中列的元素一致的行数。比如Output[0][0]=5,因为Sjm1[0][0]=366Sjm2[5][0]=366Output[1][0]=2 因为Sjm1[1][0]=104Sjm2[2][0]=104;等等)。

因此,对于前面介绍的示例,所需的输出必须如下:

我尝试在 Java 中构建一个方法,在该方法中我传递了两个 2D 整数数组,但没有按需要工作:

public static int[][] sec(int[][] Sjm1, int[][] Sorted_Sjm2) {
    int k;
    int[][] output = new int[Sjm1.length][Sjm1[0].length];
    for (int j = 0; j < Sjm1.length; j++) {
        k = 0;
        for (int m = 0; m < Sjm1[0].length; m++) {
            if (Sorted_Sjm2[j][m] == Sjm1[j][m]) {
                output[j][m] = k;
                k++;
            }
        }
    }
    return output;
}

输出显然不是我需要的:

[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]

如果有人可以帮助我,我会很高兴。

【问题讨论】:

    标签: java arrays sorting multidimensional-array columnsorting


    【解决方案1】:

    我认为您没有正确更新 k 的值,如果我理解您的需要,一旦您找到您要查找的值,只需将 k 的值更新为您在其中找到该值的索引。请注意,如果您有重复的值,它将只取第一个找到的值。

    public static int[][] sec(int[][] Sjm1, int[][] Sorted_Sjm2) {
        int k;
        int[][] output = new int[Sjm1.length][Sjm1[0].length];
        for (int j = 0; j < Sjm1.length; j++) {
            k = 0;
            for (int m = 0; m < Sjm1[0].length; m++) {
                if (Sorted_Sjm2[j][m] == Sjm1[j][m]) {
                    k = j;
                    output[j][m] = k;
                    break;
                }
            }
        }
        return output;
    }
    

    【讨论】:

      【解决方案2】:

      我对贡献有点陌生,所以如果我弄错了,请告诉我! >

      问题在于您的代码,您正在以相同的间隔比较两个矩阵(随着 m 和 j 的变化)。您可以做的是遍历矩阵 sjm2 并比较矩阵 sjm1 的每次迭代。

      1. 具有 SJM1 的值
      2. 遍历 SJM2 中的该列以找到具有相同 val 的行
      3. 在输出中添加行号。

      另外,获得输出的唯一方法是,如果您的 Sorted_Sjm2 与您的 Sjm1 相同,因为 k 每次迭代都会递增到 6。

      【讨论】:

        【解决方案3】:

        在您的内部循环(设置output[j][m])中,找到匹配索引的一种简单方法是使用List.indexOf,而不是自己搜索:

        output[j][m] = Arrays.asList(Sjm2[j]).indexOf(Sjm1[j][m]);
        

        【讨论】:

        • 我将output[j][m] = k; 替换为output[j][m] = Arrays.asList(Sjm2[j]).indexOf(Sjm1[j][m]);,但得到以下信息:[[-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]]
        【解决方案4】:

        如果你的问题没问题,问题出在k 变量上。

        它代表第二个数组上的行索引,所以当你比较两个数组上的值时,你应该用k索引第二个数组的行。

        此外,您应该在当前列中的所有行上迭代 k,因此代码将如下所示(我修改了变量以使其更具描述性):

        public static int[][] sec(int[][] Sjm1, int[][] Sorted_Sjm2) {
            int[][] output = new int[Sjm1.length][Sjm1[0].length];
        
            for (int row = 0; row < Sjm1.length; row++) {
                for (int column = 0; column < Sjm1[0].length; column++) {
                    int valueToSearchFor = Sjm1[row][column];
        
                    for (int rowInSorted = 0; rowInSorted < Sorted_Sjm2.length; rowInSorted++) {
                        if (Sorted_Sjm2[rowInSorted][column] == valueToSearchFor) {
                            // Found
                            output[row][column] = rowInSorted;
                            break;
                        }
                        // Not found
                        output[row][column] = -1;
                    }
                }
            }
        
            return output;
        }
        

        请注意,尽管此代码有效,但我怀疑它是否最佳,因此我不会将它用于非常大的数据集。

        【讨论】:

        • 我试过你的方法,但我得到 [[0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1], [2 , 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4], [5, 5 , 5, 5, 5, 5, 5], [6, 6, 6, 6, 6, 6, 6]]
        【解决方案5】:

        首先,您需要迭代Sorted_Sjm2[j][] 以找出Sjm1[j][m] 的值在哪里,因此您需要for (int m = 0; m &lt; Sjm1[0].length; m++) 中的另一个for。另一件事是为什么你使用k?k 没有在你的数组中显示任何东西。如果您想获得排序位置,您应该使用您在 new for 语句中声明的另一个变量 Sorted_Sjm2[j][]。因为我们知道你在列j,所以我们现在只需要排序数组的行号。

        public static int[][] sec(int[][] Sjm1, int[][] Sorted_Sjm2) {
            int k;
            int[][] output = new int[Sjm1.length][Sjm1[0].length];
            for (int j = 0; j < Sjm1.length; j++) {
                for (int m = 0; m < Sjm1[0].length; m++) {
                    for (int d = 0; m < Sjm1[0].length; d++) {
                        if (Sorted_Sjm2[j][d] == Sjm1[j][m]) {
                            output[j][m] = d;
                        }
                    }
                }
            }
            return output;
        }
        

        【讨论】:

        • 我尝试了您的方法,但出现以下错误:java.lang.ArrayIndexOutOfBoundsException
        【解决方案6】:

        要在排序矩阵中按该矩阵的元素列获取行索引矩阵 - 您可以首先按列对该矩阵元素的行索引进行排序,然后获取排序后的索引转置矩阵。然后将排序后的矩阵转回,并为每个元素交换其值和列索引:

        int m = 7;
        int n = 8;
        int[][] arr1 = new int[][]{
                {366, 139, 223, 312, 563, 471, 437, 2},
                {104, 195, 85, 0, 377, 289, 227, 5},
                {451, 221, 329, 425, 523, 591, 537, 1},
                {208, 78, 0, 140, 437, 380, 286, 6},
                {0, 52, 114, 84, 296, 212, 205, 3},
                {70, 0, 40, 121, 194, 156, 123, 3},
                {299, 351, 446, 216, 648, 685, 571, 2}};
        
        int[][] arr2 = IntStream
                // iterate over the indices
                // of the rows of the array
                .range(0, n)
                .mapToObj(i -> IntStream
                        // iterate over the
                        // indices of the columns
                        .range(0, m)
                        .boxed()
                        // sort indices of the elements of the
                        // columns by its values in the array
                        .sorted(Comparator.comparingInt(j -> arr1[j][i]))
                        .mapToInt(Integer::intValue)
                        // sorted column of indices
                        // is a row in the new array
                        .toArray())
                // return sorted array of indices
                .toArray(int[][]::new);
        
        // transpose the array of indices
        int[][] arr3 = new int[m][n];
        IntStream.range(0, m).forEach(i ->
                IntStream.range(0, n).forEach(j -> {
                    // swap the column index and
                    // the value of the element
                    int val = arr2[j][i];
                    arr3[val][j] = i;
                }));
        
        // output
        Arrays.stream(arr3).map(Arrays::toString).forEach(System.out::println);
        

        输出:

        [5, 3, 4, 5, 5, 4, 4, 1]
        [2, 4, 2, 0, 2, 2, 2, 5]
        [6, 5, 5, 6, 4, 5, 5, 0]
        [3, 2, 0, 3, 3, 3, 3, 6]
        [0, 1, 3, 1, 1, 1, 1, 3]
        [1, 0, 1, 2, 0, 0, 0, 4]
        [4, 6, 6, 4, 6, 6, 6, 2]
        

        另见:
        Sorting 2d array of integers by column
        Finding the position of a row element in a 2d ordered array

        【讨论】:

          猜你喜欢
          • 2022-11-19
          • 1970-01-01
          • 2020-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-24
          • 1970-01-01
          • 2013-08-17
          相关资源
          最近更新 更多