问题要从刷leetcode说起350. Intersection of Two Arrays II,在使用标准库函数qsort对数组进行排序,然后对两个已排序的数组求出其共有部分,可是提交后发现存在一个用例不过,截图如下:

完整提交代码如下:

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize)
{
    if(NULL == nums1 || NULL==nums2)
        return NULL;
    
    *returnSize =(nums1Size > nums2Size) ? nums2Size:nums1Size;
    int *res =(int *)malloc(*returnSize * sizeof(int));
    
    int i = 0;
    int j = 0;
    int k = 0;
    /*sort nums1 nums2*/
    qsort (nums1, nums1Size, sizeof(int), compare);
    qsort (nums2, nums2Size, sizeof(int), compare);
    
    while((i < nums1Size) && (j < nums2Size))
    {
        if(nums1[i] < nums2[j])
        {
            i++;
        }
        else if(nums1[i] > nums2[j])
        {
            j++;
        }
        else
        {
            res[k++] = nums1[i];
            i++;
            j++;
        }
    }
    
    *returnSize = k;
    return res;
    
}

在另一道leetcode题目中却没有测出该问题:

存在问题的原因是compare函数使用

int compare (const void * a, const void * b)
{
    return ( *(int*)a - *(int*)b );
}

假设a是1,b是-2147483648(INT_MIN),预期结果a > b应该返回正数,结果a-b得到的结果溢出为负数,因此失败,验证程序及结果:

#include <stdio.h>
#include <limits.h>
int compare (const void * a, const void * b)
{
    return ( *(int*)a - *(int*)b );
}

int main(void)
{
    int a = 1;
    int b = INT_MIN;
    printf("%d %d\n", a,b);
    printf("%d\n",compare((void *)&a,(void *)&b));
    return 0;
}

程序输出:
1 -2147483648
-2147483647

compare函数的正确形式:

int compare (const void * a, const void * b)
{
    if(*(int *)a < *(int *)b)
        return -1;
    else if(*(int *)a > *(int *)b)
        return 1;
    else 
        return 0;
}

另一种正确的,常见的compare函数形式如下:

int compare (const void * a, const void * b)
{
    return (*(int *)a > *(int *)b) -(*(int *)a < *(int *)b)
}

可是我们在搜索引擎上搜索qsort的用法时竟然惊奇的看到很地方居然都在使用错误的用法。
qsort wrong example