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

时间:2016-02-14 04:05:03

标签: java arrays int duplicates

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

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

示例:countdifference([2,4,6,8],[3,4,6,9])返回 4 ,因为4和{{1 }是重复的,剩下的数字是6283

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

9

4 个答案:

答案 0 :(得分:1)

您可以使用二进制搜索来比较数组并找出差异。您需要将此比较视为双向(< - - >),如:

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;
}

答案 1 :(得分:0)

这可能有效

     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 :(得分:0)

执行此操作的一种方法是使用removeAll()retainAll()Set方法。另一种方法是并行迭代数组,而不使用Set

为了便于使用,前两种方法将使用此帮助程序:

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的任何使用都是错误的,最后一个方法应该用while语句替换内部if循环,或者使用更简单的实现:

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 :(得分:0)

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

- (NSString *) deviceUniqueID
{
    mach_port_t iokitPort = 0;
    CFMutableDictionaryRef properties;
    IOMasterPort(0, &iokitPort);
    CFDictionaryRef serviceName = IOServiceNameMatching("charger");

    io_service_t service = IOServiceGetMatchingService(iokitPort, serviceName);

    if (service == 0)
        return nil;

    kern_return_t status = IORegistryEntryCreateCFProperties(service,
                                                             &properties,
                                                             kCFAllocatorDefault,
                                                             kNilOptions);

    IOObjectRelease(service);

    if (status == KERN_SUCCESS)
    {
        NSDictionary *dict = (__bridge NSDictionary *)(properties);
        NSData *batteryIDData = dict[@"battery-id"];

        CFRelease(properties);

        if ([batteryIDData isKindOfClass: [NSData class]])
            return [NSString stringWithUTF8String:[batteryIDData bytes]];
    }

    return nil;
}

}