【问题标题】:Java: how to compare two int[] arrays for non duplicate elements?Java:如何比较两个 int[] 数组的非重复元素?
【发布时间】:2016-05-25 02:46:06
【问题描述】:

如何比较两个 int[] 数组中的重复元素?

例如:int countDifference(int[] arrayA, int[] arrayB) 将两个已排序的数字数组作为输入,并返回仅出现在两个数组之一中的数字的数量。

示例:countdifference([2,4,6,8], [3,4,6,9]) 返回 4 因为 46 是重复的,剩余数字是2839

我有一种方法可以计算一个数组的不同元素,但不能计算两个数组的非重复元素。

import java.util.HashSet;
import java.util.Set;

public class countDistinctArray {

  public static int distinctNumberOfItems(int[] array) {
    if (array.length <= 1) {
      return array.length;
    }

    Set<Integer> set = new HashSet<Integer>();
    for (int i : array) {
      set.add(i);
    }
    return set.size();
  }

  public static void main(String args[]) {
    int array[] = { 2, 4, 6, 8, 3, 4, 6, 9 };
    System.out.println(distinctNumberOfItems(array));
  }
}

【问题讨论】:

  • 您可以使用与distinctNumberOfItems 方法相同的方法。只需添加第二个 for 循环,再次从集合中删除元素。
  • 我该如何开始呢?我在哪里放置我的 for 循环?
  • 如你所说,46是重复的,这意味着2389是非重复的,所以正确答案将是 4 的计数,而不是 3。
  • 是的对不起,它返回 4 而不是 3!你真是个天才!

标签: java arrays int duplicates


【解决方案1】:

这可能有效

     int countDifference(int[] arrayA, int[] arrayB){
         int count=0;         
         for(int i=0;i<arrayA.length;i++){
           for(int j=0;j<arrayB.length){
             if(arrayA[i]==arrayB[j])
             count++;
             else
             continue;}} }      

【讨论】:

    【解决方案2】:

    一种方法是使用SetremoveAll()retainAll() 方法。另一种方法是并行迭代数组,而不使用Set

    为了方便使用,前两种方法都会使用这个helper:

    private static Set<Integer> asSet(int[] array) {
        Set<Integer> set = new HashSet<>();
        for (int i : array)
            set.add(i);
        return set;
    }
    

    使用removeAll()实现:

    public static int countDifference(int[] array1, int[] array2) {
        // Find distinct elements in array1 that doesn't exist in array2
        Set<Integer> distinct1 = asSet(array1);
        distinct1.removeAll(asSet(array2));
    
        // Find distinct elements in array2 that doesn't exist in array1
        Set<Integer> distinct2 = asSet(array2);
        distinct2.removeAll(asSet(array1));
    
        return distinct1.size() + distinct2.size();
    }
    

    如果数组本身保证不包含重复,那么retainAll()可以找到共同的值:

    public static int countDifference(int[] array1, int[] array2) {
        Set<Integer> common = asSet(array1);
        common.retainAll(asSet(array2));
        return array1.length + array2.length - 2 * common.size();
    }
    

    上述实现都不依赖于被排序的数组。为了消除创建集合和所有值的装箱的开销,您可以使用数组的排序,并并行迭代它们:

    public static int countDifference(int[] array1, int[] array2) {
        int idx1 = 0, idx2 = 0, count = 0, val;
        while (idx1 < array1.length || idx2 < array2.length) {
            if (idx1 == array1.length) {
                val = array2[idx2];
                count++;
            } else if (idx2 == array2.length) {
                val = array1[idx1];
                count++;
            } else {
                val = Math.min(array1[idx1], array2[idx2]);
                if (array1[idx1] != val || array2[idx2] != val)
                    count++;
            }
            while (idx1 < array1.length && array1[idx1] == val)
                idx1++; // skipping 0 to many instances of val in array1
            while (idx2 < array2.length && array2[idx2] == val)
                idx2++; // skipping 0 to many instances of val in array2
        }
        return count;
    }
    

    这将是最快和最节省内存的实现。


    思想

    可以说countDifference 会认为输入3,5,5,73,5,7 有1 个差异。如果是这样,那么Set 的任何使用都是错误的,最后一个方法应该用if 语句替换内部的while 循环,或者使用更简单的实现,如下所示:

    public static int countDifference(int[] array1, int[] array2) {
        int idx1 = 0, idx2 = 0, count = 0;
        while (idx1 < array1.length && idx2 < array2.length) {
            int cmp = Integer.compare(array1[idx1], array2[idx2]);
            if (cmp != 0)
                count++;
            if (cmp <= 0)
                idx1++;
            if (cmp >= 0)
                idx2++;
        }
        return count + (array1.length - idx1) + (array2.length - idx2);
    }
    

    我个人认为这是正确的解决方案,但这取决于应如何处理数组中的重复值。如果没有重复,或者重复被认为是不同的,例如,这是最好的实现。如上例中的值 5 被计为差异。

    【讨论】:

      【解决方案3】:

      您可以使用二进制搜索来比较数组并找出差异。您需要以双向()的方式进行比较,例如:

      array1 --> array2  and  array2 --> array1
      

      因为你需要总结集合的差异。让 A 和 B 我们的集合,我们需要找到:

      (A-B) U (B-A)
      

      二分查找解决方案如下。该算法的复杂度为 O(log n)

      private static int getDifferenceBetweenTwoArray(int[] array1 , int[] array2)
      {
          int differenceCount = 0;
          //if you dont want to sort your original arrays, create temporary arrays
          int temp1[] = Arrays.copyOf(array1 , array1.length);
          int temp2[] = Arrays.copyOf(array2 , array2.length);
          Arrays.sort(temp1);
          Arrays.sort(temp2);
      
          for(Integer i : temp1)
          {
              if(Arrays.binarySearch(temp2, i) < 0)
                  differenceCount++;
          }
          for(Integer i: temp2)
          {
              if(Arrays.binarySearch(temp1, i) < 0)
                  differenceCount++;
          }   
      
          return differenceCount;
      }
      

      【讨论】:

      • 非常感谢,这就是我正在寻找的答案!
      • @EstelleVeneer 在 java 文档中它说:“Arrays.binarySearch() 方法返回搜索键的索引,如果它包含在数组中,否则返回 (-(insertion point) - 1) 。”它的意思是;如果您的数组不包含搜索键,则此方法肯定会返回一个负整数。这就是我使用
      【解决方案4】:

      如果性能不是问题,并且允许使用 java 的数据结构(如 hashset),并且数组中的数字按升序排列,那么这是一个简单的解决方案: 首先,我们将第二个数组的所有元素放入一个哈希集中,然后遍历第一个数组以查看两个数组共有多少个元素,然后返回两个数组中元素的总数,减去那些公共元素

      import java.util.*;
      
      public class CountDistinctArrays {
          public static void main(String[] args) {
              int[] arrayOne = new int[]{-1, 1, 3, 4, 6, 7, 8};
              int[] arrayTwo = new int[]{1, 2, 3, 4, 5};
      
              System.out.println(distinctNumberOfItems(arrayOne, arrayTwo));
          }
      
          public static int distinctNumberOfItems(int[] first, int[] second) {
              Set<Integer> numbers = new HashSet<Integer>();
              for (int num : second) {
                  numbers.add(num);
              }
      
              int commonElements = 0;
              for (int num : first) {
                  if (numbers.contains(num)) {
                      commonElements++;
                  }
              }
      
              return first.length + second.length - commonElements * 2;
          }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-25
        • 2016-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 2021-08-08
        相关资源
        最近更新 更多