繁体   English   中英

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

[英]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]=366 Output[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的值更新到你找到该值的索引。请注意,如果你有重复的值它只会使用它找到的第一个。

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

如果我的问题是正确的,那么问题出在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在您的数组中没有显示任何内容。 如果您想获得排序位置,您应该使用您在Sorted_Sjm2[j][]中的 new for 语句中声明的另一个变量。 因为我们知道您在第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 的每次迭代。

IE

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

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

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

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

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

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]

也可以看看:
按列对二维整数数组进行排序
在二维有序数组中查找行元素的位置

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM