c - 一种比较 C 中未排序数组值的优雅方法?

标签 c arrays

<分区>

我在 C 中有两个整数数组,我想比较它们。这是我一起破解的非常快的东西,但我想知道是否有更快的方法。

1) 找到一个不在我们正在比较的数组 (arr2) 中的整数。
2) 复制原始数组 (arr2)。
3) 遍历第一个数组 (arr1),如果在复制的数组中找到该元素,我们将那个索引处的值替换为我们知道不在原始数组中的值(这是为了防止多个时短路相同的值在数组中)。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <random.h>


bool isin(int arr[], int elem, size_t len, size_t *index) {
    int i;
    for (i = 0; i < len; ++i) {
        if (arr[i] == elem) {
            if(index != NULL)
                *index = i;
            return true;
        }
    }
    return false;
}

int notInArray(int arr[], size_t len) {
    int r;
    do {
        r = rand();
    } while (isin(arr, r, len, NULL));
    return r;
}

bool arraysEqual(int arr1[], int arr2[], size_t len) {
    size_t i, j, index;
    int notInArr2 = notInArray(arr2, len);

    int *arr = (int*)malloc(len * sizeof(int));

    for (i = 0; i < len; ++i)
        arr[i] = arr2[i]; /*copy arr2 to arr*/

    for (i = 0; i < len; ++i) {
        if (isin(arr, arr1[i], len, &index))
            arr[index] = notInArr2; /*replace that elemnt with something that we know is not in the original array*/
        else
            return free(arr), false;
    }
    free(arr);
    return true;
}

int main() {
    srand(time(NULL));
    int a[] = { 3, 9, 1, 3, 8 };
    int b[] = { 1, 8, 3, 3, 9 };
    printf("%i\n", arraysEqual(a, b, sizeof(a) / sizeof(int)));
    system("pause");
} 

我不一定要寻找源代码,但更多的是关于如何实现它的一般想法。

最佳答案

从算法的角度来看,您的解决方案不是最优的,并且在 O(n^2) 时间内执行比较(因为 isin 为数组)和 O(n) 额外空间(因为您分配了数组的副本)。

执行此任务有更便宜的方法,这里列出了 5 种替代方法:

  • 计算一个数组的哈希集或计数字典(频率分布)并迭代另一个数组以确定匹配的值直方图(O(n) 时间,O(n) 空格)
  • 与上面相同,但使用布隆过滤器,前提是您不关心匹配值频率并且不介意误报的风险(O(n) 时间,O(1) 空间)
  • 就地对其中一个数组进行排序,并使用二进制搜索来检测匹配项(O(n log n) 时间用于快速排序,O(log n)对于二进制搜索,O(1) 空间)。
  • 如果输入数组是不可变的,则执行与上述选项相同的操作,但排序到一个新数组中(时间复杂度与上述相同,但 O(n) 空间)
  • 对两个数组进行排序并检查同一索引处的所有元素是否相等(O(2n log n) 时间,O(1) 空间)。

关于c - 一种比较 C 中未排序数组值的优雅方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35112023/

相关文章:

c - 访问 C 中列表中的结构成员

c - 在 m x n 矩阵中绘制矩形、圆形或任意多边形

javascript - .forEach 与 Object.keys().forEach 在稀疏数组上的表现

C- 如何释放以下 malloced 内存

c - Libtool 为对象添加前缀,但 gcov 要求它们没有前缀

c - 尽管有足够的可用内存,但堆栈溢出

java - 使用 arraylist 删除数组中的重复项失败

arrays - 有没有一种方法可以在使用方法名称时迭代 Swift 中的元素?

c++ - 删除动态分配的数组

c - 如何使用递归计算并打印前 N 个素数