首页 > 其他分享 >字符串 hash

字符串 hash

时间:2024-04-22 21:13:01浏览次数:22  
标签:hash times 算法 base 字符串 ha

前排提示,字符串哈希所需要的数理算力、代码能力都不低。但本质很基础。

面对非“树上、图上字符串问题”:
一方面:字符串 hash 的在任何一个模型上都不是理论最优解。大常数致使几乎只能达到 \(5 \times 10^{5}\) 每秒。
另一方面:字符串 hash 的通用性、相对优性、相对易性,意味着它是实际思路下的最优解。更复杂的情况留给后续优化。

这篇文章将会让字符串 hash 以稍坏的复杂度完成:

  1. 模式串匹配算法:替代 KMP 算法、Z 算法
  2. 回文串算法:替代 manacher
  3. 循环表示算法:替代 最小表示法
  4. 最长公共前缀算法:替代线性 lcp 算法
  5. 特殊性质:
    • 常数失配匹配
    • 回文信息合并
  6. 对朴素暴力的优化性质:
    • 优化 string 作为 map 键值
    • 本质不同子串数量
    • 最长公共子串

一 字符串 hash 与 模式串匹配

1.1 hash 公式、系数、模数

对一个字符串 \(s\) ,不妨把字符权值视为它的 \(ascii\) 码,第 \(i\) 个字符权值令为 \(c_i\) 。考虑一个前缀的 hash 的表现形式: \(ha(x) = \sum_{i = 1}^{x} c_i b^{x - i}\) 。

模数:

显然需要在模意义下进行,通常取一个质数 \(p\) :选取质数的其中一个好处是 \(a \times k \bmod m\) 的落点间距是 \(gcd(a, m)\) 。

通常选取 $1e9 \sim 2e9 $ 之间的 \(p\) ,好处是 \(p\) 在 \(int\) 内,且 \(p^{2}\) 在 \(long\ long\) 内。

有素数定理,可以选 \(x \in [10^{9}, 2 \times 10^{9}]\) ,然后暴力往后找一个素数。朴素算法大概可以在几秒内完成。

系数:

系数的选取一般只需要大于字符集,小于模数即可。

1.2 multi hash

经验上,负载因子 \(\alpha\) 大时,hash 几乎没有冲突率。公式 hash 一旦冲突会误判相等(但不会误判不等)。
可以对 hash 公式更换系数 \(b\) 和模数 \(p\) 得到其他公式。多个公式得到的 hash 值同时相等才认为相等,使冲突率可以更低。

1.3 用于模式串匹配的字符串 hash

综合上述原因,字符串哈希可以表达成:

\[ha_{h, x} = (\sum_{i = 1}^{x} ha_{h, i - 1} \times base_{h}^{x - i} + c_{x}) \bmod p_{h} \]

第 \(h\) 重哈希,考虑到前缀 \(x\) ,系数是 \(base_h\) ,模数是 \(p_{h}\) 。

再进一步,将多重 hash 的数组封装成一个类(容器会很慢并且不够面向对象),重载构造函数和等号。于是可以方便地调用多重 hash 值。

1.4 子串哈希值

由于 hash 公式是下降幂的形式,让 \(l\) 的前缀 hash 进行补幂后,被 \(r\) 的前缀 hash 减去。

\[\begin{aligned} ha_{l, r} &= (\sum_{i = 1}^{r} c_i \times base^{i} - \sum_{i = 1}^{l - 1} c_i \times base^{i} \times base^{r - l}) \bmod p \\ &= (ha_r - ha_l \times base^{r - l}) \bmod p \\ \end{aligned} \]

1.5 模式串匹配的常见模型

1.5.1 平凡模式串匹配

平凡模式串匹配:给一个文本串 \(text\) 和一个模式串 \(pattern\) ,询问 \(pattren\) 在 \(text\) 中出现过多少次。

根据 1.1 - 1.4 的述描述,可以写出伪代码:

function solve(text, pattern):
  cnt = 0
  ha1 = get_hash(text)
  ha2 = get_hash(pattern)
  for i : 1 to n - m + 1:
    if ha1.subhash(i, i + m - 1) == ha2:
      cnt += 1
  return cnt

参考列题:http://oj.daimayuan.top/course/22/problem/908

1.5.2

二 字符串 hash 与 回文串

标签:hash,times,算法,base,字符串,ha
From: https://www.cnblogs.com/zsxuan/p/18150771

相关文章

  • 【每周例题】力扣 C++ 分割字符串
    分割字符串题目 题目分析1.先确定用容器存储,容器的存储结构如下图所示: 2.这个题目的话,第一反应应该是用到动态规划,下面是动态规划的模板:res=[]ans=[]defbacktrack(未探索区域,res,path):if未探索区域满足结束条件:res.add(ans)#深度拷贝......
  • 什么是hashCode 以及 hashCode()与equals()的联系
    1、什么是hashCode:hashCode就是对象的散列码,是根据对象的某些信息推导出的一个整数值,默认情况下表示是对象的存储地址。通过散列码,可以提高检索的效率,主要用于在散列存储结构中快速确定对象的存储地址,如Hashtable、hashMap中。为什么说hashcode可以提高检索效率呢?我们先看一个例......
  • JTCR-处理字符串-15
    Java将字符串作为String类型的对象,不像其他语言,以字符数组的方式实现。字符串创建之后就不可修改。进行修改相关操作返回的是新字符串,原先的字符串不会发生变化。将字符串以不可变的方式实现是为了更有效率。与String对应的StringBuffer和StringBuilder类创建之后可以修......
  • 字符串
    我要成为字符串领域大神!trie树/字典树字典树是什么思想?我们先设定一个根节点,一般为0,每次加入新字符串时都与其相连。比如我们要插入string,看起来就是这样然后如果我们又插入一个strange,就会变成这样也就是说插入的时候可以直接继承志曾经出现过的前缀部分,思想就是这么个思......
  • python中列表、字典和字符串的互相转换
    我们在python使用中经常会用到需要把字符串转为list或者字典,及把list或字典转为字符串(写文件,f.write()只能写字符串,插入数据库时,也只能用字符串)具体使用方法总结了一下:1、字符串转lists='a,b,c'l=s.split(',')  #把字符串s以逗号分割,分割出的list给到l ......
  • SQL Server 中将字符串按数字排序
    方法一:使用CAST或CONVERT我们可以使用CAST或CONVERT函数将字符串转换为数字,然后按照数字进行排序。示例如下:SELECT*FROMYourTableORDERBYCAST(YourColumnASINT)方法二:使用TRY_CAST或TRY_CONVERT如果我们不确定字符串中的所有值都可以成功转换为数字,我们可......
  • python os库将字符串转化为路径
    前言在python编程中,经常需要对文件进行读取操作,而os库提供了一些方法处理文件和目录的路径官方文档如下:https://docs.python.org/zh-cn/3/library/os.html本文主要记录如何将字符串转化为路径1.os.path.join()主要将多个字符串进行拼接,从而形成路径importosos.path.join......
  • hashlib模块
    摘要算法:只能加密不能解密加密算法:用方法加密加密后的字符串可以解密【一】什么是摘要算法Python的hashlib提供了常见的摘要算法如MD5SHA1等等。摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表......
  • 在 C 中打印字符串 - 如何在 C 中打印字符串
    打印字符串是编程中的一项基本操作。它帮助您输出信息,检查和调试您的代码,并向用户显示提示信息。在本文中,您将学习在C中打印字符串的一些不同技术。(本文视频讲解:java567.com)在C中字符串是什么?字符串是一系列字符,如字母、数字或符号,它们被组合在一起。它用于在程序中表示文......
  • 2024-04-21---真题--一个字符串中的最长重复子串(滑动窗口变种)
    真题-一个字符串中的最长重复子串(滑动窗口变种)题目:思路:首先这不是求公共子串,所以不需要动态规划记录。然后一个string相当于就是一个Char[],所以直接滑动窗口来枚举最好做。说白了,这道题就是求abc|abc的问题。其实就是可以看作是一个大的滑动窗口(包含两个小的窗口),并且大的窗口......