繁体   English   中英

如何在C中比较两个数组?

[英]how to compare two arrays in c?

我正在创建一个可以比较两个数组的函数。 如果它们相同,则返回1;否则,则返回0。

它要求程序以线性时间运行,因此我无法使用for-for循环进行比较。 有什么建议吗?

加扰后应返回的数组示例:

a = {10,15,20}, b = {10,15,20}
a = {1,2,3,4,5}, b = {5,3,4,2,1}
a = {}, b = {} (i.e. len = 0)
a = {2,1,3,4,5}, b = {1,2,4,3,5}

加扰的数组应返回0的示例:

a = {1,1}, b = {1,2}
a = {10,15,20}, b = {10,15,21}
a = {1,2,3,4,5}, b = {5,3,4,2,2}

如果您可以为数组元素指定一个最大值,则只需循环遍历每个元素并计数存在的值,就可以非常轻松地在线性时间内比较它们,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_ARRAY_VALUE 100

bool compare_arrays(int * arr1, size_t arr1_size,
                    int * arr2, size_t arr2_size)
{

    /*  Set up array to count elements  */

    int * table = calloc(MAX_ARRAY_VALUE + 1, sizeof * table);
    if ( !table ) {
        perror("couldn't allocate memory");
        exit(EXIT_FAILURE);
    }

    /*  Increment index if element is present in first array...  */

    for ( size_t i = 0; i < arr1_size; ++i ) {
        table[arr1[i]]++;
    }

    /*  ...and decrement index if element is present in second array.  */

    for ( size_t i = 0; i < arr2_size; ++i ) {
        table[arr2[i]]--;
    }

    /*  If any elements in array are not zero, then arrays are not equal  */

    for ( size_t i = 0; i < MAX_ARRAY_VALUE + 1; ++i ) {
        if ( table[i] ) {
            free(table);
            return false;
        }
    }

    free(table);
    return true;
}

int main(void) {
    int a1[] = {10, 20, 30, 10};
    int a2[] = {20, 10, 10, 30};
    int a3[] = {1, 4, 5};
    int a4[] = {1, 3, 5};

    if ( compare_arrays(a1, 4, a2, 4) ) {
        puts("a1 and a2 are equal");        /*  Should print  */
    }
    else {
        puts("a1 and a2 are not equal");    /*  Should not print  */
    }

    if ( compare_arrays(a3, 3, a4, 3) ) {
        puts("a3 and a4 are equal");        /*  Should not print  */
    }
    else {
        puts("a3 and a4 are not equal");    /*  Should print  */
    }

    if ( compare_arrays(a1, 4, a4, 3) ) {
        puts("a1 and a4 are equal");        /*  Should not print  */
    }
    else {
        puts("a1 and a4 are not equal");    /*  Should print  */
    }

    return 0;
}

输出:

paul@horus:~/src/sandbox$ ./lincmp
a1 and a2 are equal
a3 and a4 are not equal
a1 and a4 are not equal
paul@horus:~/src/sandbox$ 

无需指定最大值,就可以遍历每个数组并找到最大值。 它仍然是线性时间,但是如果没有上限,您可能最终会得到一个巨大的索引表。

由于两个数组的比较与元素的顺序无关,因此必须先对两个数组进行排序,然后才能进行比较。 因此,您不能在线性时间内执行此操作。 您可以做的最好是O(n log n) ,因为这是大多数排序算法的最佳顺序。

我的C很生锈,因此下面的脚本可能存在一些内存问题。 但是,基本任务是对2个数组进行排序,逐个元素比较它们。 如果它们都匹配,则scramble应返回1,否则为0。

以下脚本可用于GCC,尚未使用其他任何编译器进行过测试。 它比较长度相等的数组。 长度不等的情况留给OP作为次要练习。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare_ints(const void * a , const void * b)
{
    const int * ia = (const int *)a;
    const int * ib = (const int *)b;
    return *ia > *ib;
}

int scramble(const int * a, const int * b, unsigned int len)
{
    int * sorted_a = malloc(len * sizeof(int));
    int * sorted_b = malloc(len * sizeof(int));

    memcpy(sorted_a, a, len * sizeof(int));
    memcpy(sorted_b, b, len * sizeof(int));

    qsort(sorted_a, len, sizeof(int), compare_ints);
    qsort(sorted_b, len, sizeof(int), compare_ints);

    for (int i = 0; i < len; i++)
    {
        if (sorted_a[i] != sorted_b[i])
        {
            free(sorted_a);
            free(sorted_b);
            return 0;
        }
    }

    free(sorted_a);
    free(sorted_b);
    return 1;
}

int main (int argc, char const *argv[])
{
    int a[3] = {20, 10, 15};
    int b[3] = {10, 15, 20};
    int is_equal = scramble(a, b, 3);

    printf("is_equal = %i\n", is_equal);
    return 0;
}

仅供参考:您不能在线性时间内做到这一点。 qsort具有O(n log n)

在某种程度上,您可以获得第一个数组的所有哈希值的总和,并将其与第二个数组的哈希值的总和进行比较。 可以,但是我不知道确切是什么。

这是我的尝试,到目前为止,我所有的测试都给出了积极的结果:

#include <stdio.h>

unsigned int hash(unsigned int x) {
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = ((x >> 16) ^ x);
    return x;
}

int compareArrays(int *arr1, int *arr2, int size) {

    if (size == 0) return 1;

    unsigned long  sum1 = 0;
    unsigned long  sum2 = 0;

    for (int i = 0; i < size; ++i)  {
        sum1 += hash(arr1[i]);
    }
    for (int i = 0; i < size; ++i) 
        sum2 += hash(arr2[i]) ;

    return sum1 == sum2;
}

int main(void) {
    int a[] = {1,2,3,4,5,6,7,8,255};
    int b[] = {1,2,3,4,5,6,7,8,9};
    int size = 9;
    printf("Are they the same? %s.\n", compareArrays(a, b, size) ? "yes" : "no");
    return 0;
}

您可以使用以下格式的memcmp函数:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

例如;

/* memcmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char buffer1[] = "abcde";
  char buffer2[] = "abcde";

  int n;

  n=memcmp ( buffer1, buffer2, sizeof(buffer1) );

  if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
  else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
  else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);

  return 0;
}

输出为:

'abcde' is same as 'abcde'.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM