Hash——快速判断两个字符串是否相等

\(\text{Hash}\)原理#

散列表(\(\text{Hash Table}\),也叫哈希表),是根据关键码值(\(Key~value\))直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。

若关键码值为 \(k\),则其值存放在 \(f(k)\) 的存储位置上。由此,不需比较便可直接取得所查记录。其中这个对应关系 \(f()\) 叫做 散列函数

对不同的关键字可能得到统一散列地址,即 \(k_1 \ne k_2\),而 \(f(k_1) = f(k_2)\),这种现象称为碰撞(冲突)。


字符串\(Hash\)#

算法梗概#

用以快速判断两个字符串是否相等。

\(hash[1 \dots i]\)表示字符串中首字符到第 \(i\)个字符的哈希值。

\[hash[1 \dots i] = (hash[1 \dots i-1] \times k +str[i])~\%~p \]

其中:

  • \(k\) 可以取字符串元素种类,但更常取 \(31,~131\)等特殊数字。
  • \(p\) 取较大的质数,保证取模后的解集合的规模尽量的大。
    也可以直接用 unsigned 型来存储,看作对 \(2^{32}\)\(2^{64}\) 取模,采用这种自然溢出方法的 \(\text{Hash}\),已经证明可以被特殊构造的字符串卡掉

如果不放心的话可以多取几个大的质数分别取模判断,二次或多次 \(\text{Hash}\)

性质#

\(k\) 进制,对 \(p\) 取模,则有:

\[hash[1 \dots i] = (hash[1 \dots i-1] \times k +str[i]) ~ \% ~ p \]

即:

\[hash[1 \dots i] = (str[1]\times k^{i-1} + str[2] \times k^{i-2} + \dots + str[i-1] \times k + str[i])~\%~p \]

由此也可推出字符串从第\(i\)项到第\(j\)项的\(hash\)值为:

\[hash[i \dots j] = (str[i] \times k^{j-i} + str[i+1] \times k^{j-i-1} + \dots + str[j-1] \times k + str[j])~\%~p \]

那么如果我们已知\(hash[i \dots t] (i<t<j)\)\(hash[t+1 \dots j]\),该如何求出\(hash[i \dots j]\)呢?(即字符串的合并)

\[hash[i \dots j] = ((hash[i \dots t] \times k^{j-t})~\%~p + hash[t+1 \dots j])~\%~p \]

处理完合并,在已知\(hash[1 \dots j]\)\(hash[1 \dots i-1]~(2<i<j)\)的情况下,又应该怎样求出\(hash[i \dots j]\)呢?(即字符串的拆分)

\[hash[i \dots j] = (hash[1 \dots j] - (hash[1 \dots i-1] \times k^{j-i+1}) ~\%~ p) ~\%~ p \]

已知两端字符长度与 \(hash\) 值,可以进行快速的合并。

已知前缀 \(hash\) 值,可以快速求出区间 \(hash\) 值。

作者:chy12321

出处:https://www.cnblogs.com/chy12321/p/14844797.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Chy12321  阅读(1299)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu