在按列排序的二维数组中查找二维数组元素的索引

Finding indexes of 2d array elements in a sorted 2d array by columns

我有两个相同维度的整数二维数组需要比较。我将用一个示例来解释我需要什么,其中 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 中构建一个方法,我在其中传递了两个二维整数数组,但没有按需要工作:

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]

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

如果我答对了你的问题,那么问题出在 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;
}

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

首先您需要迭代 Sorted_Sjm2[j][] 以找出 Sjm1[j][m] 值在哪里,因此您需要另一个 for in for (int m = 0; m < Sjm1[0].length; m++)。另一件事是为什么你使用 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;
}

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

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

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

此外,获得输出的唯一方法是 Sorted_Sjm2 与 Sjm1 相同,因为每次迭代时 k 递增到 6。

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

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

我认为你没有正确更新 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;
}

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

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]

另请参阅: