简体   繁体   中英

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

I have two 2D arrays of integers of the same dimension that I need to compare. I am going to explain what I need with an example where Sjm1 is the "original" array and the Sjm2 array has the same values as Sjm1 but the values of each column are ordered in increasing order (ie "0" is the min value of Sjm1 in column 0 so Sjm2[0][0]=0 ; then "70" is the next min value of Sjm1 in column 0 ⇒ Sjm2[1][0]=70 ; and so on). I have a method to sort a "Sjm1" array to "Sjm2".

源矩阵

排序矩阵

Now I need to build an "output" array (2D array of integers) where the values in each column represent the number of the row in Sjm1 array that coincides with the elements of the column in Sjm2. For example, Output[0][0]=5 because Sjm1[0][0]=366 is Sjm2[5][0]=366 ; Output[1][0]=2 because Sjm1[1][0]=104 is Sjm2[2][0]=104 ; and so on).

Thus, for the previously presented example, the needed output must be the following:

预期结果

I tried to build a method in Java where I pass the two 2D arrays of integers but is not working as needed:

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

The output is clearly not what I need:

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

I'll be glad if someone can help me.

I think you are not updating the value of k correctly, if I understood what you need, once you find the value you are looking for just update the value of k to the index you found the value in. Note that if you have repeated values it will only take the first it found.

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

If I get your question right, the problem is with the k variable.

It represents the row index on the second array, so when you compare the value on the two array, you should index the row of the second array with k .

Also, you should iterate the k over all rows in the current column, so the code would look like this (I modified the variables to make them more describing):

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

Note that although this code works, I doubt that it's optimal, so I would not use it for very large data sets.

At first you need to iterate on Sorted_Sjm2[j][] to find out where is the Sjm1[j][m] value so you need another for in for (int m = 0; m < Sjm1[0].length; m++) . And the other thing is why you are using k?k doesn't show any thing in your array. If you want gain the sorted position you should use another variable that you declare in new for statement in Sorted_Sjm2[j][] . Because we know you are in column j so we just need to now row number of the sorted array.

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

I'm kinda new to contributing, so please let me know if I got this wrong! ><"

The problem is with your code, you're comparing both of the matrices at the same intervals (as m and j changes). What you could do, is iterate through matrix sjm2 and compare for each iteration for matrix sjm1.

ie

  1. Have value of SJM1
  2. Iterate through that column in SJM2 to find the row with the same val
  3. Add the row number in the output.

Plus, the only way you got your output is if your Sorted_Sjm2 is the same as your Sjm1, as k was incremented to 6 every iteration.

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

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

To get a matrix of row indices by columns of elements of this matrix in a sorted matrix - you can first sort the row indices of the elements of this matrix by columns and get the sorted transposed matrix of indices. Then transpose the sorted matrix back and, for each element, swap its value and column index:

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

Output:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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