解决Java中的以下问题的最佳方法是什么? 有3个具有相同行数和列数的二维数组:
Array1:
[1]: {1, 2, 3}
[2]: {2, 2, 4}
[3]: {1, 1, 1}
Array2:
[1]: {1, 2, 0}
[2]: {1, 2, 3}
[3]: {1, 0, 1}
Array3:
[1]: {1, 1, 1}
[2]: {1, 2, 3}
[3]: {1, 0, 1}
我需要找出所有数组中存在的行的索引。在上面的例子中,答案应该是: [1],[2],[2]
数组1 [1] :{1,2,3}
ARRAY2: [2] :{1,2,3}
ARRAY3: [2] :{1,2,3}
更新:是否有内置功能可以执行此操作?或者FOR循环是唯一的解决方案吗?
答案 0 :(得分:1)
我会做以下事情:
hashcode
和equals
。HashMaps
HashMaps
编辑#2,意识到需要反转映射。
private Map<MyClass, Integer> map(int[] array){
Map<MyClass, Integer> arrayMap = new HashMap<>();
for (int i; i<array.length; i++)
arrayMap.put(new MyClass(array[i]), i);
}
private mySearch(){
int[] array1, array2, array3;
Map<MyClass, Integer> map1 = map(array1);
Map<MyClass, Integer> map2 = map(array2);
for (int i=0; i<array3.lenght; i++){
MyClass row = new MyClass(array3[i]);
Integer array1Row = map1.get(row);
Integer array2Row = map2.get(row);
if (array1Row != null && array2Row != null){
// Matching rows found
}
}
}
答案 1 :(得分:1)
首先,编写一个名为AreRowsEqual()
的函数,它比较两行。所以,现在,问题已重新定为Find similar elements in 3 arrays
。
其次,尝试根据先前的知识考虑一个与您已经知道的最接近的解决方案:要在两个数组中找到相等的元素,您需要一个双嵌套for循环。那么,要在三个数组中找到相等的元素,你需要一个三重嵌套循环,对吗?
好的,现在,把它作为一个坏的,坏的,坏的解决方案,因为它的时间复杂度是 O(n ^ 3)。我们应该能够做得更好。
考虑一下:为了使一个元素在所有3个数组中相似,首先它必须在前两个中相似;然后,它必须在接下来的两个中相似。这种算法的复杂性类似于 O(x * n),其中x是数组的数量。好多了,对吧? (我无法弄清楚O()究竟是什么,帮助任何人?)编辑:原来它是O((n ^ 2)*(x-1)),这是一个当n> 0时,比O(n ^ 3)好很多x - END EDIT 顺便提一下,这可以让您忘记严格3
数组的要求,只考虑一些x
数组。
我写了一个方法,收到一个upvote,然后我意识到它不会工作,我删除它。这是另一种尝试,我相信它会起作用:
创建一个二维整数数组。我们称之为“矩阵”。此矩阵将包含x
列,行数将是第一个数组的行数。 (是的,即使您的数组具有不同的长度,这也会起作用。)此矩阵的单元格中的数字将匹配行索引。因此,例如,在我描述的算法完成之后,矩阵中的一行{ 1, 3, 2 }
将告诉我们第一个数组的第1行与第二个数组的第3行和第三个数组的第2行匹配。我们将使用-1
来表示“不匹配”。
因此,矩阵的第一列需要使用第一个数组的所有行的索引进行初始化,即使用数字0, 1, 2, ... n
,其中n
是元素的数量。第一个数组。
对于每个附加数组,按如下方式填充矩阵中的列:循环遍历矩阵中当前列的每一行,并按如下方式计算单元格:如果前一列的相应单元格为-1
,将-1
带到此单元格中。否则,在当前数组中查找与前一个数组的相应行匹配的行,如果找到,则将其索引存储到此单元格中。否则,在此单元格中存储-1。
对所有数组重复,即对矩阵中的所有列重复。最后,匹配的行是矩阵最后一列中没有-1
的行。
如果真的关心效率,你可以按照John B的建议去做,并编写一个名为Row
的不可变类,它封装(包含对行的引用)并实现{{ 1}}和hashCode()
。 equals()
可以使用equals()
来实现。 Arrays.deepEquals()
中可能还有一些名为Arrays
的礼物,否则您需要自己动手。
答案 2 :(得分:1)
AFAIK没有内置功能。
您需要编写自己的函数来实现它(使用for
循环)。
发布一些代码以显示您尝试过的内容,如果它不能正常工作或进行优化。
答案 3 :(得分:1)
检查此代码:
ArrayList<Integer[]> arr1 = new ArrayList<Integer[]>();
arr1.add(new Integer[]{1,2,3});
arr1.add(new Integer[]{2,2,5});
arr1.add(new Integer[]{1,1,1});
ArrayList<Integer[]> arr2 = new ArrayList<Integer[]>();
arr2.add(new Integer[]{1,2,0});
arr2.add(new Integer[]{1,2,3});
arr2.add(new Integer[]{1,0,1});
ArrayList<Integer[]> arr3 = new ArrayList<Integer[]>();
arr3.add(new Integer[]{1,1,1});
arr3.add(new Integer[]{1,2,3});
arr3.add(new Integer[]{1,0,1});
for (int r = 0 ; r < arr1.length() ; r++) {
for(int s = 0 ; s < arr2.length() ; s++){
for(int t = 0 ; t < arr3.length() ; t++){
if(Arrays.deepEquals(arr1.get(r), arr2.get(s))){
}else
{
continue;
}
if(Arrays.deepEquals(arr1.get(r), arr3.get(t))){
System.out.println(r + " " + s + " " +t);;
}
}
}
}
答案 4 :(得分:0)
编写一个接受两个参数的方法:要搜索的二维数组,一维数组行。如果未找到匹配项,则返回-1,否则返回匹配行的索引。
对于第一个数组的每一行: 2A。调用从第一个数组和Array2传递行的方法。 2B。如果2a返回&gt; 0,则调用传递相同行的方法和Array3
如果2b返回&gt; 0,则输出返回的索引。
答案 5 :(得分:-1)
检查Arrays.deepEquals()方法。它会检查两个数组是否相等。