求救.........字符串Hash 如何实现

adfsssd 2007-07-11 04:14:25
求一个字符串Hash 表的实现例子。

请高手多指教一下.

搞了几天了,也没搞定,唉,,头晕了。
...全文
341 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yalexfan 2007-07-12
  • 打赏
  • 举报
回复
哦,谢谢
iambic 2007-07-12
  • 打赏
  • 举报
回复
字符串hash用的数字不止一种。最常见的是37,Java API中的String.hashCode()用的就是37。127是《C算法》中用的。还有个数字很常用,忘了是多少。
yalexfan 2007-07-12
  • 打赏
  • 举报
回复
static int hash(char *key)
{
int h = 0, a = 127, i;
for(i = 0; key[i]; ++i)
h = (a * h + key[i]) % NELEMS(symtab);
return h;
}

a选127有什么考虑么?我以前看到过使用37的。
是否有什么实践的经验?分享一下啦
chai2010 2007-07-12
  • 打赏
  • 举报
回复
刚重新给你整理了一个。
好久没写hash表了.


#include <assert.h>
#include <string.h>

// 计算数组大小

#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))

/* 保存标号的哈希表 */

static struct symtab
{
struct symtab *link;
char *key;
} *symtab[211];

static int hash(char *key)
{
int h = 0, a = 127, i;
for(i = 0; key[i]; ++i)
h = (a * h + key[i]) % NELEMS(symtab);
return h;
}

// 添加

void insert(const char *key)
{
assert(key != NULL);
assert(strlen(key) > 0);

struct symtab *p;
int h = hash(key);

p = symtab[h];
while(p != NULL) {
if(!strcmp(key, p->key)) return;
p = p->link;
}
if(p == NULL) {
int len = strlen(key);
p = malloc(sizeof(*p) + len + 1);
assert(p != NULL);

p->key = (char *)(p + 1);
strcpy(p->key, key);

p->link = symtab[h];
symtab[h] = p;
}
return p->val;

}

// 删除(比较复杂)

bool delete_key(const char *key)
{
assert(key != NULL);
assert(strlen(key) > 0);

struct symtab **pp;
int h = hash(key);

for (pp = &symtab[h]; *pp; pp = &(*pp)->link)
if (!strcmp(key, (*pp)->key) == 0) {
struct symtab *p = *pp;
*pp = p->link;
free(p);
return true;
}
return false;
}

/* 查询 */

bool search(const char *key)
{
assert(key != NULL);
assert(strlen(key) > 0);

struct symtab *p;
int h = hash(key);

p = symtab[h];
while(p != NULL) {
if(!strcmp(key, p->key)) return true;
p = p->link;
}
return false;
}

chai2010 2007-07-12
  • 打赏
  • 举报
回复

/* 保存标号的哈希表 */
static struct symtab {
struct symtab *link;
char *key, *val;
} *symtab[211];

static int
hash(char *key)
{
int h = 0, a = 127, i;
for(i = 0; key[i]; ++i)
h = (a * h + key[i]) % NELEMS(symtab);
return h;
}

/* 生成新的地址标号 */
char *new_id(void)
{
static char id[6+1] = "@AAAAA";
static int i = 0;
char *p = malloc(sizeof id);
if(p == NULL) error("overflow");
if(id[5] >= 'Z') error("too many id");
id[(i++)%6]++; strcpy(p, id);
return p;
}

/* 获取变量对应的CASL标号 */
char *get_id(char *key)
{
struct symtab *p;
int h = hash(key);

p = symtab[h];
while(p != NULL) {
if(!strcmp(key, p->key)) return p->val;
p = p->link;
}
if(p == NULL) {
int len = strlen(key);
p = malloc(sizeof(*p) + len + 1);
if(p == NULL) error("overflow");
p->key = (char *)(p + 1);
strcpy(p->key, key);
p->val = new_id();
p->link = symtab[h];
symtab[h] = p;
}
return p->val;
}

/* 定义所有的变量 */
void def_id(void)
{
int i;
for(i = 0; i < NELEMS(symtab); ++i) {
struct symtab *p;
p = symtab[i];
while(p != NULL) {
emit("%s\tDC 1\t; -> %s", p->val, p->key);
p = p->link;
}
}
}

这是我以前做的小编译器中用到的hash表。
是用于处理tiny语言中出现的标号。

iambic 2007-07-11
  • 打赏
  • 举报
回复
不懂就抄一个好了。何必还找别人代抄。
CathySun118 2007-07-11
  • 打赏
  • 举报
回复
http://burtleburtle.net/bob/hash/doobs.html
hilary0810 2007-07-11
  • 打赏
  • 举报
回复
搞不定就直接用stl好了,已经封装好了,干嘛还费尽自己写
bargio_susie 2007-07-11
  • 打赏
  • 举报
回复
有问题找百度。。。。

http://hi.baidu.com/wertywang/blog/item/1fe7d2ee1faaed282cf5340f.html
adfsssd 2007-07-11
  • 打赏
  • 举报
回复
自己顶一下

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧