在C中非常简单的地图实现(用于辅导目的)?

时间:2009-08-05 17:03:57

标签: c map code-snippets code-reuse

我有一个程序可以读取文件中的URL并在每个URL主机上执行gethostbyname()。这个电话很费劲。我想缓存它们。

C中是否有一个非常简单的基于地图的代码片段,我可以用来进行缓存? (我只是不想重新发明轮子。)

必须具备以下几点:

  • 使用许可许可的开源<(认为BSD或公共域名)。
  • 非常简单:理想情况下小于100 LOC
  • 键为char*,值为void*。无需复制它们。
  • 无需实施remove(),但需要contains()put()应替换该值。

PS:我将它标记为 homework ,因为它可能是。我只是非常懒惰,并且想要避免在重新实现时遇到的所有常见陷阱。

8 个答案:

答案 0 :(得分:5)

Christoper Clark's hashtable implementation非常简单。它超过100行,但不是很多。

Clark的代码似乎已作为并行化示例进入Google's Conccurrency Library

答案 1 :(得分:5)

这是一个非常简单和天真的

  • 固定铲斗尺寸
  • 无删除操作
  • 插入替换键和值,并可以选择释放它们

#include <string.h>
#include <stdlib.h>

#define NR_BUCKETS 1024

struct StrHashNode {
    char *key;
    void *value;
    struct StrHashNode *next;

};

struct StrHashTable {
    struct StrHashNode *buckets[NR_BUCKETS];
    void (*free_key)(char *);
    void (*free_value)(void*);
    unsigned int (*hash)(const char *key);
    int (*cmp)(const char *first,const char *second);
};

void *get(struct StrHashTable *table,const char *key)
{
    unsigned int bucket = table->hash(key)%NR_BUCKETS;
    struct StrHashNode *node;
    node = table->buckets[bucket];
    while(node) {
        if(table->cmp(key,node->key) == 0)
            return node->value;
        node = node->next;
    }
    return NULL;
}
int insert(struct StrHashTable *table,char *key,void *value)
{
    unsigned int bucket = table->hash(key)%NR_BUCKETS;
    struct StrHashNode **tmp;
    struct StrHashNode *node ;

    tmp = &table->buckets[bucket];
    while(*tmp) {
        if(table->cmp(key,(*tmp)->key) == 0)
            break;
        tmp = &(*tmp)->next;
    }
    if(*tmp) {
        if(table->free_key != NULL)
            table->free_key((*tmp)->key);
        if(table->free_value != NULL)
            table->free_value((*tmp)->value);
        node = *tmp;
    } else {
        node = malloc(sizeof *node);
        if(node == NULL)
            return -1;
        node->next = NULL;
        *tmp = node;
    }
    node->key = key;
    node->value = value;

    return 0;
}

unsigned int foo_strhash(const char *str)
{
    unsigned int hash = 0;
    for(; *str; str++)
        hash = 31*hash + *str;
    return hash;
}

#include <stdio.h>
int main(int argc,char *argv[])
{
    struct StrHashTable tbl = {{0},NULL,NULL,foo_strhash,strcmp};

    insert(&tbl,"Test","TestValue");
    insert(&tbl,"Test2","TestValue2");
    puts(get(&tbl,"Test"));
    insert(&tbl,"Test","TestValueReplaced");
    puts(get(&tbl,"Test"));

    return 0;
}

答案 2 :(得分:3)

C ++中的

std::map是一个红黑色的树;使用an existing red-black tree implementation in C怎么样?我联系的那个更像是700 LOC,但它的评论非常好,从我对它的粗略一瞥中看起来很清醒。你可以找到其他人;这是Google在“C红黑树”上首次曝光。

如果你对性能不挑剔,你也可以使用不平衡的二叉树或最小堆或类似的东西。使用平衡二叉树,您可以保证O(log n)查找;对于不平衡树,查找的最坏情况是O(n)(对于按顺序插入节点的病态情况,所以最终会得到一个非常长的分支,就像链接列表一样),但是(如果我生锈了)内存是正确的)平均情况仍为O(log n)。

答案 3 :(得分:2)

您可以尝试使用以下实现

clib

答案 4 :(得分:1)

memcached

不是代码段,而是高性能的分布式缓存引擎。

答案 5 :(得分:1)

不要懒惰,要避免写这些东西是非常明智的。

这个library如何从未使用过它,但它似乎声称可以按照你的要求去做。

答案 6 :(得分:1)

Dave Hanson的C Interfaces and Implementations包括一个很好的哈希表,以及许多其他有用的模块。哈希表的时钟频率为150行,但这包括内存管理,高阶映射函数和转换为数组。该软件是免费的,这本书值得购买。

答案 7 :(得分:0)

在此处找到了一个实现:c文件和h文件,它与您提出的内容非常接近。 W3C许可证