Java - 比较2个int数组并根据它们的值来判断它们

时间:2012-11-07 19:27:28

标签: java arrays compare

我有一组包含相同数量的2个int数组

例如

int[] array1 = {1,3,5,5,2}
int[] array2 = {5,3,4,4,4}

我需要根据2个标准对它们进行比较

  1. 在同一索引上有多少元素具有相同的值
  2. 在不同的索引上有多少元素具有相同的值
  3. 返回一个表示值

    的整数数组

    我有几个例子,所以你可以更好地理解:

       int[] array0 = {1,3,5,5,2};
       int[] array1 = {5,3,4,4,4};
       int[] array2 = {5,3,4,4,5};
       int[] array3 = {2,3,2,2,4};
       int[] array4 = {5,5,2,1,3};
       int[] array5 = {3,1,5,5,2};
       int[] array6 = {1,3,5,5,2};
    
       compare(array0,array1); //this would return 1,1
       compare(array0,array2); //this would return 1,2
       compare(array0,array3); //this would return 1,1
       compare(array0,array4); //this would return 0,5
       compare(array0,array5); //this would return 3,2
       compare(array0,array6); //this would return 5,0
    

    对于第一个数字很容易,我只需要检查array1的索引i上的元素是否与array2中的相同。

    我在生成第二个数字时遇到问题,因为应该采用其中一个数组中的最小数字。 如果我只是查看array1的元素是否在array2中的某个位置,它会在某些情况下产生错误的结果。

    如果你看看

    int[] array1 = {1,3,5,5,2}
    

    int[] array3 = {2,3,2,2,4};
    

    并检查array1是否与索引上的array3具有相同的内容,它将返回3个数字相等,但是在不同的位置上是错误的,因为它应该从最低的数字判断并且结果应该是1。

    如果我切换它以比较array3在某个索引上是否与array1具有相同的内容,它适用于这种情况但不适用于其他情况。

    关于如何处理这个问题的任何想法,我都很无能为力?

7 个答案:

答案 0 :(得分:1)

  • 克隆两个输入整数数组。

  • 检查并查看元素在同一索引上是否具有相同的值。

  • 如果是这样,请将1添加到同一索引计数器,并将输入整数数组中的值更改为-1(或小于最小有效值的数字)。

  • 使用嵌套for循环检查元素是否具有相同的值。换句话说,检查第一个整数数组的第一个元素是否包含第二个整数数组的所有元素。跳过两个数组中具有相同索引的元素,并跳过小于最小有效值的元素。

  • 如果是这样,将1添加到不同的索引计数器,并将输入整数数组中的值更改为-1(或小于最小有效值的数字)。

答案 1 :(得分:0)

也许对于第二个条件,你可以尝试从数组中删除数字,并在找到匹配后突破循环。您可以将临时数组设置为原始数组的值。然后针对array1[0]中的所有值检查array3的值。找到匹配项后,从两个数组中删除该数字,然后针对array1[1]中的所有值检查array3

因此,当您针对array1[4]核对array3[0]时,您将获得匹配。然后你将删除这两个数字并打破循环。在array1中无法检查更多数字,因此结果为1。

我认为这样可以解决两次计算相同值的问题。

答案 2 :(得分:0)

你可以拥有一个已经访问过数字的集合。您会喜欢:(不测试此代码是否运行,只是为了给您一个想法)

public int[] compare(int[] first, int[] second) {
     Set<Integer> numbersFoundInFirstArray = new LinkedHashSet<Integer>();
     Set<Integer> numbersFoundInSecondArray = new LinkedHashSet<Integer>();
     int inSameIndex = 0;
     int inDifferentIndex = 0;

     for (int i; i < first.length; i++) {
         if (first[i] == second[i]) {
             inSameIndex++;
         }
         if (numbersFoundInFirstArray.contains(second[i])) {
             inDifferentIndex++;
         }
         if (numbersFoundInSecondArray.contains(first[i])) {
             inDifferentIndex++;
         }
         numbersFoundInFirstArray.add(first[i]);
         numbersFoundInSecondArray.add(second[i]);
     }
     return new int[] {inSameIndex, inDifferentIndex};
}

如果我很清楚,集合中的包含比较有O(1)。 Set的属性是你只有一个特定类型的元素。因此,如果你添加1次,它将只有一个引用1.这样,你只会测试当前的数字是否已在另一个数组中找到:)

答案 3 :(得分:0)

您需要将所有数组转换为树状结构,该结构基本上会索引所有数组中的所有唯一值,并将指针存储到数组中的位置和哪个数组。该树的基本蓝图结构为:

uniqElemVal->arrayIndx->arrayID = true

如果uniqElemVal为1,3,5,2,1,3,5,2,2,3,4,2,3,2,2,2,4等,则全部加入工会

arrayIndx将在第一个数组0中为1,因为5将为2和3等。

数组ID是任意的,可让您键入每个数组,例如1为第一个,2为第二个等。

所以在这种情况下:

#1st array
1->0->1
3->1->1
5->2->1
5->3->1
2->4->1

#2nd array
2->0->2    
3->1->2 
3->2->2
2->3->2
2->4->2
4->5->2

然后,当遍历此树时,只要有一个包含多个叶子的第二级节点,就意味着在多个数组的特定位置中该特定元素值匹配。

我个人将这棵树定义为

HashMap<Integer, HashMap<Integer, ArrayList<Integer>>>

因此,每当你有一个包含&gt; 1个元素的叶子数组列表时,就意味着你有一个匹配

答案 4 :(得分:0)

首先,这听起来真的很糟糕。不要返回一个数组,其中每个索引意味着不同的东西和神秘的东西。制作两个方法:compareSameIndex(array,array)和compareDifferentIndex(array,array)。

对于如何实际实现这些,你可以检查第一个数组中的每个索引,看看它们是否出现在第二个数组中的任何位置,只调用compare()。然后compareDifferentIndex()变为compare() - compareSameIndex()。例如:

public int compare (int[] array0, int[] array1) {
  int matches = 0;
  List<Integer> list1 = Arrays.asList(array1);

  for (int curInt : array0) {
    if (list1.contains(curInt)) {
      matches++;
    }
  }
  return matches;
}

public int compareSameIndex(int[] array0, int[] array1) {
  int matches = 0;
  for (int i=0; i < array0.length; i++) {
    if (array0[i] == array1[i]) {
      matches++
    }
  }
  return matches;
}

public int compareDifferentIndex(int[] array0, int[] array1) {
  return compare(array0, array1) - compareSameIndex(array0, array1);
}

当相同的数字出现两次时会发生什么情况,但是您可以将该逻辑构建为compare()以适应,这些要求似乎有些模糊。你也可以为非常大的数组优化这个,你不会两次检查相同的数字,但这将是我采取的一般方法。

答案 5 :(得分:0)

检查参数只是一种很好的做法。 可能有一些小的优化可以在这里完成,但是Hash会让你存储你已经访问过的位置,以便不再计算它们一次。

 private int[] compare(int[] arr1, int[] arr2){
    int same_index = 0;
    Hashtable differences = new Hashtable();
    int diff_count = 0;
    if (arr1.length != arr2.length){
        throw new IllegalArgumentException("Array Size is not identical.");
    } else {
       for(int count = 0; count < arr1.length; count++){
          if (arr1[count] == arr2[count]{
              same_index++;
              differences.put(count, null);
          } else {
              for (int count2 = 0; count2 < arr1.length; count2++){
                  if(!differences.containsKey(count2) && arr1[count] == arr2[count2]){
                      differences.put(count2, null);
                      diff_count++;
                  }

              }                  
          }
       }
    }
    int[] returnArray = new int[2];
    returnArray[0] = same_count;
    returnArray[1] = diff_count;
    return (returnArray);
 }

答案 6 :(得分:0)

这应该可以解决问题:

public void compare(int[] arrayA, int[] arrayB) {
    int sameIndex = 0;
    int diffIndex = 0;
    //Made two new empty arrays to save the status of each element in the corresponding array, whether it has been checked our not, if not, it'd be null.
    String[] arrayAstatus = new String[arrayA.length];
    String[] arrayBstatus = new String[arrayB.length];
    for (int i = 0; i < arrayA.length; i++) {            
        if (arrayA[i] == arrayB[i] || arrayAstatus[i] != null) {
            sameIndex++;
            continue;
        }
        for (int a = 0; a < arrayB.length; a++) {
            if (a == i || arrayBstatus[a] != null) {
                continue;
            }
            if (arrayA[i] == arrayB[a]) {
                arrayAstatus[i] = "checked";
                arrayBstatus[a] = "checked";
                diffIndex++;
                break;
            }
        }
    }
    System.out.println(sameIndex + ", " + diffIndex);
}