字符串hash

  这个是在学习哈希表的时候偶然带出来的,想着都是hash家的人,一起看看,结果比哈希表难好多【或许是哈希表学的不深入】; 

解决问题:

  字符串hash主要应用在:寻找长度为n的主串S中的匹配串T(长度为m)出现的位置次数的问题属于字符串匹配问题。【将KMP一起看了,这种问题用KMP也可以解决啊,而且人家KMP的代码短啊,,也是不太清楚字符串hash存在的意义是啥,,】如果是从主串中每次选出两个子串判断是否匹配问题,还是要用字符串hash求解

主要思路:

  1》将字符串中的每一个字母都看做是一个数字(例:从a-z,视为1-26);

  2》选取两个合适的互质常数 b,h ( b < h )【互质,有用;b < h,有用too】;

  3》定义哈希函数,H(C)=[ c1*b^(m-1) + c2*b^(m-2) + . . . + c0*b^0 ] mod h

      【看不懂吧,看不懂就对了,我也看不懂hhhh~

         (1) C代表一个字符串,用C=c1 c2 c3 c4..cm;表示该字符串,其中 ci 表示从前向后数的第 i 个字符;

         (2) 方括号[ ]内的表达式:c1*b^(m-1) + c2*b^(m-2) + . . . + c0*b^0 意为将字符串C当做 b进制数 来处理,b是基数;

         (3) 关于对 h 取模,若b,h有公因子,那么不同的字符串取余之后的结果发生冲突的几率将大大大增加(冲突:数值相同的意

              思) 

        】;

  4》计算上一步H(C)的过程是递归实现的:H(C,k)为前 k 个字符构成的字符串的哈希值,(若不考虑取模):

        H(C,k+1)= H( C , k ) * b+c( k+1 );

  5》判断 主串上 长度为 n 的任意子串 C '=c(k+1) c(k+2) c(k+3) . . . c(k+n) 与 待匹配串S=s1 s2 s3. . .sn 的哈希值是否相等【现在子串长度为n!!】,则:

         H(C ’)= H( C , k+n ) - H(C, k ) * b^n; 

   【我全部都看明白之后还是有点懵,感觉和用遍历没什么差别,,看看了看分析,因为运算是递归的,所以主串中前 i 字符的哈希值是打表存储好的,取子串时直接调用相减函数就可以,此时需要计算的只有b^n,还是省去很多比对的过程的】

  6》思路在第五步就已经结束了,我看完也在翘首期盼着“考虑取模”的讲解,其实在实际应用中,通常利用32/64位无符号整数来计算哈希值的,这样的话,当哈希值溢出时,系统会自动对h=2^32 / h=2^64取模

不足之处:

  对于哈希值在 0~n 内均匀分布的哈希函数,出现不同字符串哈希值相等的期望步数是O(sqrt(n)),这在选择哈希函数时可以作为一个效率和正确性的参考。

  即便如此,我们还可以再双哈希降低出现相同哈希值的概率,即取不同的模数,把不同的模数算出来的哈希值都记下来,只有几个哈希值都一样,我们才能判定字符串的匹配,我们通常用双哈希就可以相冲突的概率降到最低,如果分别取 h1=10^9+7和h=10^9+9,就几乎不可能发生冲突,因为他们是一对孪生质数

 

 

 

 

 

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值