c语言哈希表字符串,【C语言】哈希函数写法、字符串深度复制

Little trick.

1 哈希函数

理想的哈希函数保证每个字符串对应唯一的哈希值。下面这个哈希函数是同学在项目中遇到的。

unsigned int hash(char* s)

{

unsigned int h=0;

for(;*s;s++)

h = *s + h*31;

return h%HASHSIZE; //predefined hash size

}

可以看出,这个hash函数遍历字符串中每个字符,通过将其ASCII码计算得到最终的哈希值h。 这样来确保前面提到的结果唯一性。 我们在gdb中验证一下,有char*类型的字符串s为nnmm。s的第i个字符用s[i]或者*(s+i)表示。

(gdb) p s

$8 = 0x40071c "nnmm"

(gdb) p s[0]

$11 = 110 'n'

(gdb) p s[1]

$12 = 110 'n'

(gdb) p s[2]

$13 = 109 'm'

(gdb) p *s

$9 = 110 'n'

(gdb) p *s+1

$10 = 111

(gdb) p *(s+1)

$14 = 110 'n'

(gdb) p *(s+2)

$15 = 109 'm'

可以看到,直接打印第i个字符的同时也会输出该字符的ASCII码。 第i个字符在公式中转成ASCII码,然后算出unsigned int型的h。

ASCII码对照表

9fb5e7e62c361485561fce55ec2eebee.png

1.1 哈希函数的对比

[1]中提到编程珠玑中的一个hash函数也是用的类似方法,代码如下:

//用跟元素个数最接近的质数作为散列表的大小

#define NHASH 29989

#define MULT 31

unsigned in hash(char *p)

{

unsigned int h = 0;

for (; *p; p++)

h = MULT *h + *p;

return h % NHASH;

}

除此之外,[1]还对常用字符串哈希函数 BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash进行了量化比较。

1.2 哈希函数分类

[2]中把哈希函数分为如下几类:

加法Hash;

位运算Hash;

乘法Hash;

除法Hash;

查表Hash;

混合Hash;

其中我们上文的函数属于乘法Hash,这种类型的Hash函数利用了乘法的不相关性(乘法的这种性质,最有名的莫过于平方取头尾的随机数生成算法,虽然这种算法效果并不好)。

jdk5.0里面的String类的hashCode()方法也使用乘法Hash。不过,它使用的乘数是31。推荐的乘数还有:131, 1313, 13131, 131313等等。

Reference

2 字符串深度复制

char* str_dump(char* s)

{

int l=strlen(s)+1;

char* ns=(char*)malloc(l*sizeof(char));

strcpy(ns,s);//char *strcpy(char* dest, const char *src)

return ns;// possible be NULL

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值