【问题标题】:Determine whether two sets of integers are the same, faster than N log(N)判断两组整数是否相同,比N log(N)快
【发布时间】:2013-09-21 10:44:40
【问题描述】:

我遇到了这个问题:

给定两个数字数组,找出这两个数组中的每一个是否具有相同的整数集。建议一种算法,它可以比N * log(N) 运行得更快而无需额外空间。

这是链接

find-if-two-arrays-contain-the-same-set-of-integers

algorithm-to-tell-if-two-arrays-have-identical-members

但是在阅读了上述链接的所有答案后,我没有找到我遇到的这个简单的答案,这里是......

int main(){
    int a[] = {1,5,5,7,5,6,6};
    int b[] = {1,6,6,5,7,5,9};

    int i = 0;
    int size = 0;
    int xor_ab = a[0]^b[0];
    int sumDiff_ab = (a[0] - b[0]);;

    if(sizeof(a)/sizeof(a[0]) == sizeof(b)/sizeof(b[0])){
        size = sizeof(a)/sizeof(a[0]);
    }else{
        printf("not identical : array size differ");
        return 0;
    }

    for(i=1; i < size ; ++i){
        xor_ab = xor_ab ^ a[i] ^ b[i];
        sumDiff_ab += (a[i] - b[i]);
    }
    if(xor_ab == 0 && sumDiff_ab == 0){
        printf("identical");
    }else{
        printf("not identical");
    }
    return 0;
}

现在我想知道,我的解决方案是否适用于所有用例。 如果没有,请让我知道这些用例。

[编辑]

请考虑数组中的所有数字都是 +ve。

[接受的答案]

我接受了@Boris Strandjev 的回答,

我的解决方案不适用于此类情况

{3,5}

{1,7}

【问题讨论】:

  • 我看不出异或的意义。数组未排序。

标签: c algorithm


【解决方案1】:

这是一个您的算法将无法工作的示例:

a[] = {3, 5};
b[] = {1, 7};

从两个数组中计算出的两个值 - 太多不同的数组集将评估为相同的两个值。这种身份比较永远不会奏效(考虑所有可能发生的冲突)。

【讨论】:

  • 正是我想要的。
【解决方案2】:

这适用于 a[] 和 b[] 的有限大小以及 a[] 和 b[] 中值的有限范围:

#include <stdio.h>

unsigned primes[] = {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71
                ,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149 };

int main(void)
{
unsigned a[] = {1,5,5,7,5,6,6};

#if SHOULD_BE_EQUAL
unsigned b[] = {1,5,5,6,7,5,6};
#else
unsigned b[] = {1,6,6,5,7,5,9};
#endif

#define COUNTOF(x) (sizeof x / sizeof x[0])

unsigned pa, pb, idx;

for (pa=1,idx=0 ; idx < COUNTOF(a); idx++) pa *= primes[a[idx]];
for (pb=1,idx=0 ; idx < COUNTOF(b); idx++) pb *= primes[b[idx]];

printf("A[] and b[] are %s equal\n", (pa==pb) ? "completely" : "not" );

return 0;
}

【讨论】:

  • 有趣的方法,虽然我倾向于认为简单的位图会更好。
  • 位图不会出现重复(例如 a[] 数组中的两个五)
【解决方案3】:

也许这不会回答你的问题,但是使用散列函数来比较数组呢?

#include <stdio.h>
#include <stdlib.h>
#include <openssl/sha.h>
int main(){
    int a[] = {1,5,5,7,5,6,6};
    int b[] = {1,5,5,7,5,6,6};

    unsigned char hasha[SHA_DIGEST_LENGTH]; // == 20
    unsigned char hashb[SHA_DIGEST_LENGTH]; // == 20

    SHA1((char*) a , sizeof(a), hasha);
    SHA1((char*) b , sizeof(b), hashb);

    printf("Are arrays equals ? %d\n" , (strcmp(hasha,hashb)==0? 1:0));

    return 0;
}

你可以编译它:

 gcc test.c -lssl -lcrypto -o test

【讨论】:

  • 那为什么不使用像 openssl 这样的库来做散列呢?
  • 我的问题是关于我上面提到的解决方案,如果它会失败。我想知道用例。就像@Boris Strandjev 提到的那样
  • 好的,我只是想添加一个使用库来处理繁重工作的解决方案。但我知道我没有回答你的问题。
  • @KarolyHorvath 我同意只是因为对于这种特殊情况,这个答案可能更适合作为问题中链接的问题之一的答案。 Alternate ways to solve the problem are usually OK.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
相关资源
最近更新 更多