C 使用什么数据结构?(哈希映射与trie与?)

C 使用什么数据结构?(哈希映射与trie与?),c,data-structures,hashmap,trie,C,Data Structures,Hashmap,Trie,我有一个C函数,它可以生成大约600万个独特的数组。这些数组始终每个都有17个元素,每个元素都是0到16之间的整数。我还有一个稍微修改过的函数版本,它还将生成大约600万个相同类型的独特阵列。我的问题是,第二个比第一个少产生45000个结果,我想看看这些结果是什么 所以我的方法是简单地存储第二个函数的所有结果(计算器告诉我这不应该超过400 mb,这可以保存在内存中),然后查找第一个函数的结果,打印出不存在的结果 假设一般的方法是有意义的(如果没有,请告诉我),我要寻找的是一个合适的数据结构(最

我有一个C函数,它可以生成大约600万个独特的数组。这些数组始终每个都有17个元素,每个元素都是0到16之间的整数。我还有一个稍微修改过的函数版本,它还将生成大约600万个相同类型的独特阵列。我的问题是,第二个比第一个少产生45000个结果,我想看看这些结果是什么

所以我的方法是简单地存储第二个函数的所有结果(计算器告诉我这不应该超过400 mb,这可以保存在内存中),然后查找第一个函数的结果,打印出不存在的结果

假设一般的方法是有意义的(如果没有,请告诉我),我要寻找的是一个合适的数据结构(最好是用C语言实现的),它可以容纳大约600万个数据的唯一排列

[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
(或其某些转换),然后对其执行快速成员资格测试。正如标题所说,我确实怀疑哪些数据结构可以完成这项工作,但我不确定尝试或哈希图是否是最佳选择


这是一种检测另一种算法中缺陷的算法,而不是将在生产中使用的算法。我感兴趣的是以一种编码的方式来完成这项工作,并以人的方式相对快速地返回结果,而不一定是以毫秒为单位,因此,存在能够完成大部分工作的易于搜索的库肯定是一个优势。

取决于您的情况下哪一个库可以获得更好的内存性能。另外,您使用什么样的散列函数,如何解决冲突等。检查一个

最优性如何取决于排列的分布方式以及插入与搜索的比率。因为你不关心最优性,只想用一种简单的方法来检验假设,而不必整夜等待结果,我的直觉说:

整数[0,16]可以表示为五位数字,因此其中十七位可以表示为85位(11字节)的二进制字符串。因此,您可以使用许多库中的一个来存储经过排序/哈希处理的字符串集,并对其进行成员资格测试,这是可以完成的。它的速度和缓存一致性不如调优的trie,但它足以在几秒钟内完成66mb的数据,午餐前就可以完成

如果没有这样的库可以方便地使用,并且您必须从头开始工作,那么我只需要创建一个字符串的排序列表,然后通过二进制搜索进行成员资格测试。结果是O(n logn+m(n logn))=O(2×mn logn)eg,二次时间为m→N如果这只是在生产过程中作为脱机作业运行一次或两次,那就足够了;如果您打算一天不止一次地执行此操作,我会担心缓存的局部性,并使用trie或B树。

保持简单:

  • 将每个排列表示为17字节的数组
  • 将整个较小的集合存储为上述数组(17*6M<98MB)
  • 按字典顺序对其排序,这样
    qsort
    的比较器只需调用
    memcmp(左、右、17)
  • 对于较大集合中的每个元素,使用二进制切块在排序数组中查找它(使用与前面相同的比较器,这次使用
    bsearch

最后两个步骤中的每一步都将执行大约6M*log(6M)的比较,即大约138M。这可能比编写代码所需的时间还要少。这并不长,因为一切都很简单:-)

@Steve Jessop您可以在线性时间内完成最后一步,通过删除我们正在搜索的数组中不需要的值来进行更智能的搜索:

假设n是A的大小,m是B的大小

int counter_A = 0;
int counter_B = 0;
int counter_C = 0;
while(counter_A != n){
    int temp = A[counter_A];
    counter_A++;
    //Removes all elements at the beginning of B since they are inferior than all
    //elements in A because they are inferior than the minimum of A
    for(;counter_B < m && B[counter_B] < temp;counter_B++);
    if((counter_B < m && B[counter_B] > temp) || counter_B == m){
        C[counter_C] = temp;
        counter_C++;
    }
}
int计数器A=0;
int计数器_B=0;
int计数器_C=0;
while(计数器A!=n){
int temp=A[计数器A];
计数器A++;
//删除B开头的所有元素,因为它们低于所有元素
//A中的元素,因为它们低于A的最小值
对于(;counter_Btemp)|计数器B==m){
C[计数器C]=温度;
计数器C++;
}
}

这应该在O(n+m)时间内执行,因为算法的每一步都至少执行一次计数器递增。

我认为您需要权衡C中的值,以避免通信

我将把C中的每个数组逐行打印为空格分隔的整数。然后从文件中加载它,创建一组字节数组,如下所示(F代码):

然后计算两个文件之间的集差,如下所示:

load "file1.txt" - load "file2.txt"
这可能需要几分钟才能运行。

a)创建一个包含两个64位int的结构

b) 因为每个结果有17个元素,所以将前8个元素相乘,将结果放在第一个整数上,将其他7个元素相乘,将结果放在第二个整数上

c) 为您的结构创建运算符<

d) 创建一组结构并插入第一次运行的所有结果

e) 迭代第二次运行结果并执行set::find()

类结果
{
公众:
结果(int arr[17]);//填写_n1和_n2
布尔运算符<(常量结果和r)常量//比较
{ 
如果(_n1!=r._n1)
返回_n1SetResult;
SetResult SetResult;

Edwin

到目前为止,我还没有哈希函数。我对问题进行了编辑,以表明数组是唯一生成的,因此不应该发生冲突(如果我正确理解注释的话)。哈希的性能将取决于哈希函数以及它们将数组映射到的哈希位置,这将决定所需内存的范围。特里肯
load "file1.txt" - load "file2.txt"
class Result
{
public:
    Result(int arr[17]);              // Fill-in _n1 and _n2

    bool operator < (const Result& r) const  // Compare
    { 
        if (_n1 != r._n1)
           return _n1 < r._n1;
        return _n2 < r._n2;
    }

protected:
    int _n1;
    int _n2;
};

typedef std::set< Result > SetResult;
SetResult setResult;