在按列排序的二维数组中查找二维数组元素的索引
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]=366
是 Sjm2[5][0]=366
; Output[1][0]=2
因为 Sjm1[1][0]=104
是 Sjm2[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 的每次迭代。
即
- 有SJM1的价值
- 遍历 SJM2 中的该列以找到具有相同值的行
- 在输出中添加行号。
此外,获得输出的唯一方法是 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]
另请参阅:
•
•
我有两个相同维度的整数二维数组需要比较。我将用一个示例来解释我需要什么,其中 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]=366
是 Sjm2[5][0]=366
; Output[1][0]=2
因为 Sjm1[1][0]=104
是 Sjm2[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 的每次迭代。
即
- 有SJM1的价值
- 遍历 SJM2 中的该列以找到具有相同值的行
- 在输出中添加行号。
此外,获得输出的唯一方法是 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]
另请参阅:
•
•