在3个二维数组中查找类似的行

时间:2012-01-09 11:52:10

标签: java arrays multidimensional-array

解决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循环是唯一的解决方案吗?

6 个答案:

答案 0 :(得分:1)

我会做以下事情:

  • 创建一个在数组中占用一行的类,并实现hashcodeequals
  • 将前两个数组中的每一行(包含在上面的类中)插入两个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. 编写一个接受两个参数的方法:要搜索的二维数组,一维数组行。如果未找到匹配项,则返回-1,否则返回匹配行的索引。

  2. 对于第一个数组的每一行: 2A。调用从第一个数组和Array2传递行的方法。 2B。如果2a返回&gt; 0,则调用传递相同行的方法和Array3

  3. 如果2b返回&gt; 0,则输出返回的索引。

答案 5 :(得分:-1)

检查Arrays.deepEquals()方法。它会检查两个数组是否相等。