【问题标题】:What is a simple C library for a set of integer sets?什么是一组整数集的简单 C 库?
【发布时间】:2010-03-23 13:58:24
【问题描述】:

我必须修改一个 C 程序,并且我需要包含一组无符号整数集。也就是说,我有数百万个整数集(每个整数集包含 3 到 100 个整数),我需要将它们存储在某种结构中,我们称之为目录,它可以在对数时间内告诉我给定的整数集已存在于目录中。唯一需要对目录定义的操作是查找和插入。

这在内置对有用数据结构的支持的语言中会很容易,但我是 C 的外国人,并且在 Google 上环顾四周确实(令人惊讶地)没有令人满意地回答我的问题。这个项目看起来不错:

http://uthash.sourceforge.net/

但我需要想出自己的哈希密钥生成器。

这是一个标准的、简单的问题,所以希望有一个标准的、简单的解决方案。

【问题讨论】:

    标签: c integer set


    【解决方案1】:

    这取决于您要如何处理数据。但也许tsearch 已经做了你想要的。您还可以为每个集合构建一个排序数组并使用 bsearch 查找值,尽管在插入过程中性能可能会受到影响。

    编辑:如果您正在寻找(外部)库,您会发现一些 C 和 C++ 哈希表实现 here 的比较。这篇文章的作者写了一个通用的头文件实现,叫做khash。所以你编译的二进制文件没有任何额外的依赖。

    【讨论】:

    • tsearch 非常适合管理通用元素的二叉树。它不会添加两次元素,因此我们可以将它用于集合。
    【解决方案2】:

    编辑:对不起,我开始回答是因为它是 C++ 而不是 C。是的,那么你应该找到你的哈希函数并自己编码......因为你已经知道它的集合的平均维度没那么难,只要选择一个好的哈希函数!但是,如果您想检查目录是否已经存在,则需要将整个集合编码为一个数字。

    您可以尝试迭代地散列集合中的单个数字:

    int hashcode = initvalue
    for (int i = 0; i < 0; ++i)
      hashcode = calc_code(hashcode, number_set[i], i);
    

    散列函数依赖于其先前的值、当前数字和当前索引。

    STL 集呢?

    #include <set>
    
    int nums[6] = {1,6,34,2,67,41};
    set<int> numbers;
    
    for( int i = 0; i < 6; ++i ) numbers.insert(nums[i]);
    
    for( set<int>::const_iterator iter = numbers.begin(); iter != numbers.end(); ++iter )
      cout << *iter << ' ';
    

    使用这种数据结构,您可以轻松地存储所有集合,但您还需要一种方法来检查一个集合是否已包含在目录中。不清楚:您想知道目录中是否已经存在具有所有 SAME 元素的集合?

    您可以通过检查所有元素手动执行此操作,但由于您有数百万个元素,您应该找到一种方法以唯一编号散列集合的元素并使用集合映射..

    【讨论】:

    • OP问了一个C程序,STL是纯C++的。
    • STL 用于 C++,这个问题被标记为“C”
    • 是的,抱歉,我编辑了它:) 刚醒来.. 还是有点模糊
    【解决方案3】:

    如果我理解正确,你想表示一组我认为不是特别琐碎的整数集。

    第一点是表示一组整数。最简单的方法是使用这样的可变大小数组:

    typedef struct { 
      int size;
      int elems[1];
    } intset;
    

    您可以使用

    创建一个新集合(具有固定数量的元素)
    intset *newset(int size) 
    { 
      intset *set;
      set = malloc(sizeof(intset) + sizeof(int)*(size-1));
      if (set) set->size = size;
      return set;
    }
    

    并使用set-&gt;elems[0]=i1; ... 存储元素。

    另一种选择是使用位数组,但实现将取决于要存储的整数的性质(例如,它们是否在固定范围内?它们通常以组的形式出现吗?)。

    一旦你有了你的整数集合,你将需要一个比较函数(以确定两个集合是否具有相同的元素)。如果您选择一个数组来表示一个集合,并且保持该数组排序,那么检查两个集合是否相同非常简单;如果是位图,则取决于您如何实现它。

    现在,对于集合的集合,您可以选择一个(排序的)向量,您可能需要在插入元素时不时调整其大小,或者是一个哈希表。在后一种情况下,您需要为您的整数集编写一个哈希函数(可能使用现有函数!)。

    正如我所说,这对我来说似乎不是微不足道的,我并不惊讶谷歌没有提供帮助。

    不过,这并不是非常复杂,您只需要在继续之前做出一些决定。

    【讨论】:

    • 我很惊讶听到这不是微不足道的,因为在其他语言中(甚至是具有 STL 的类似 C++),这将是微不足道的。整数值是无符号的,并且在某个固定范围内(如在运行时已知的范围内,而不是编译时已知的范围内),在大多数情况下在 0 到 1000 万之间,但在某些情况下在 0 到高达 1 亿之间。如果我使用哈希表,是否会想到任何哈希函数? zoborist 散列在这里合适吗?
    【解决方案4】:

    自己实现一个简单的哈希表。当你知道如何自己实现一个程序员时,它会让你成为一个更好的程序员。

    http://en.wikipedia.org/wiki/Hash_table

    【讨论】:

    • 我自己实现这个可能会让我成为一个更好的程序员。但是,这并不是一个很好的答案。如果我只是想成为一个更好的程序员,我可能会花时间做更好的练习。此外,我不太可能实施性能最佳的解决方案,而且高性能的解决方案可能会花费我很多时间来实施。我觉得奇怪的是,没有像 C++ 的 STL 这样的库可以给我一个简单的解决方案,而我需要重新发明(或重新实现)轮子。
    • 你并没有真正回答问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 2010-09-07
    • 2010-09-25
    • 2011-09-24
    • 2021-08-13
    • 2022-01-21
    相关资源
    最近更新 更多