如何检查两个大小相等的数组在C中是否具有相同的值? (复杂度O(n))

时间:2016-07-26 03:31:49

标签: c arrays permutation

编辑:元素的值范围从0到99,范围是0到99。 这甚至可能吗?我试过使用下面的代码,但这显然是错误的:

#include <stdio.h>

int scrambled(unsigned int a[], unsigned int b[], unsigned int len) {
    if (len = 0) {
        return 1;
    } else {
        int sumA, sumB, i;
        for (i = 0; i < len; i++) {
            sumA += a[i];
        }
        for (i = 0; i < len; i++) {
            sumB += b[i];
        }
        if (sumA == sumB) {
            return 1;
        } else {
            return 0;
        }
    }
}

我假设具有相同值总和的两个数组也具有相同的值,但事实并非如此。 {2,2}{3,1}具有相同的总和,但不是相同的值。

有没有办法可以检查一个数组是否是线性复杂度时间的另一个数组的排列?

4 个答案:

答案 0 :(得分:1)

是的,在C ++中使用hash:

#include <iostream>
#include <unordered_set>

bool isEqual(int a1[], int a2[], int len) {
  using namespace std;
  unordered_set<int> s1(a1, a1 + len); //O(n)
  unordered_set<int> s2(a2, a2 + len); // O(n)
  return s1 == s2; // O(n)
}

int main() {
  using namespace std;
  int a1[5] = {5,2,3,4,1};
  int a2[5] = {1,3,2,5,4};
  std::cout << isEqual(a1, a2, sizeof(a1) / sizeof(int)) << std::endl;

  int a3[5] = {0,2,3,4,5};
  int a4[5] = {1,6,2,5,4};
  std::cout << isEqual(a3,a4, sizeof(a3) / sizeof(int)) << std::endl;
  return 0;
}

如果您的数据中存在相同的值,请将unordered_set兑换为unordered_multiset

另外:     http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp

  

复杂度按比例调用n调用operator == on value_type,调用   到key_eq返回的谓词,并返回对hasher的调用   通过hash_function,在平均情况下,与最差的N2成比例   N是容器大小的情况。

更快的计划:  根据您的数据实现自定义哈希表。例如,您的数据集范围是多少?你在一个数组中有多少个数字?

答案 1 :(得分:1)

如果数组中元素的值足够小,则可以保留大小等于数组中最大值的零arr数组。然后,对于一个数组A,您可以遍历元素并将arr中的相应元素标记为1。然后对于其他数组B,执行相同操作并检查A中是否有任何不在B中的元素。

#include <stdio.h>
#define MAX 10000
int arr[10000];
int scrambled( unsigned int a[], unsigned int b[], unsigned int len)
{
    if (len=0)
    {
    return 1;
    }
    else
    {
        for (int i=0; i<len; i++)
        {
            arr[A[i]] = 1;
        }
        int same = 1;
        for (int i=0; i<len; i++)
        {
            if(arr[B[i]] != 1)
                same = 0;
        }
        if (same)
        {
            return 1;
        }
        else    
        {
            return 0;
        }
    }
}

答案 2 :(得分:1)

如果您可以修改数组,可以使用基数排序对它们进行排序,并将它们与简单的for循环进行比较。基数排序的时间复杂度为 O(N * log(maxN)),其中maxN是数组中任何数字的最大值。对于unsigned int的数组,此最大值是常量,因此时间复杂度为 O(N)

答案 3 :(得分:0)

我不会说英语而且我不是专业的开发人员

打赌我现在明白了这个问题。

我认为这个问题是你没有重置'sumA','sumB'变量

sumA和sumB有一个垃圾值

我认为你这样做

int sumA = 0, sumB = 0, i;