简体   繁体   English

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

[英]how to compare two arrays in c?

I am creating a function which can compare two arrays. 我正在创建一个可以比较两个数组的函数。 It returns 1 when they are the same and return 0 when they are not. 如果它们相同,则返回1;否则,则返回0。

It required the program run as linear time, so i cannot use a for-for loop to compare it. 它要求程序以线性时间运行,因此我无法使用for-for循环进行比较。 Any suggestions for me? 有什么建议吗?

Examples of arrays for which scrambled should return 1: 加扰后应返回的数组示例:

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}

Examples of arrays for which scrambled should return 0: 加扰的数组应返回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}

If you can specify a maximum value for the array elements, you can compare them in linear time pretty easily, by just looping through each one and counting the values which are present, like so: 如果您可以为数组元素指定一个最大值,则只需循环遍历每个元素并计数存在的值,就可以非常轻松地在线性时间内比较它们,如下所示:

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

which outputs: 输出:

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$ 

Without specifying the maximum value, you can loop through each array and find the maximum. 无需指定最大值,就可以遍历每个数组并找到最大值。 It'll still be linear time, but without an upper bound you might end up with a huge index table. 它仍然是线性时间,但是如果没有上限,您可能最终会得到一个巨大的索引表。

Because the comparison of the two arrays is independent of the order of the elements, both must be sorted before they can be compared. 由于两个数组的比较与元素的顺序无关,因此必须先对两个数组进行排序,然后才能进行比较。 Because of this, you can't do this in linear time. 因此,您不能在线性时间内执行此操作。 The best you can do is O(n log n) , as that is the best order of most sorting algorithms. 您可以做的最好是O(n log n) ,因为这是大多数排序算法的最佳顺序。

My C is pretty rusty so the may be some memory problem with the script below. 我的C很生锈,因此下面的脚本可能存在一些内存问题。 However, the basic task is to sort the 2 arrays, compare them element by element. 但是,基本任务是对2个数组进行排序,逐个元素比较它们。 If they all match, scramble should return 1, other it's 0. 如果它们都匹配,则scramble应返回1,否则为0。

The script below works with GCC, haven't tested it with any other compiler. 以下脚本可用于GCC,尚未使用其他任何编译器进行过测试。 It compares arrays of equal length. 它比较长度相等的数组。 The case of unequal length is left for the OP as an minor exercise. 长度不等的情况留给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;
}

FYI: you can't do it in linear time. 仅供参考:您不能在线性时间内做到这一点。 qsort has O(n log n) . qsort具有O(n log n)

At a certain extent, you can obtain the sum of all the hashed values of the first array, and compare it to the sum of the hashed values of the second array. 在某种程度上,您可以获得第一个数组的所有哈希值的总和,并将其与第二个数组的哈希值的总和进行比较。 It'll work, but I don't know precise it is. 可以,但是我不知道确切是什么。

Here is my attempt, all my tests have given positive results so far : 这是我的尝试,到目前为止,我所有的测试都给出了积极的结果:

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

You can use memcmp function with this format: 您可以使用以下格式的memcmp函数:

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

For example; 例如;

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

output is: 输出为:

'abcde' is same as 'abcde'.

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

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