标签:存储 seek 假设 pow 转换 位置 变量 实现 signed
哈希算法与 \(KMP\) 算法是两种处理字符串问题的常用算法
哈希算法是通过构造一个哈希函数,将一种数据转化为可用变量表示或者是可作数组下标的数
哈希函数转化得到的数值称之为哈希值
通过哈希算法可以实现快速匹配与查找
一般用于寻找一个字符串的匹配串出现的位置或次数
对于哈希函数的构造,通常选取两个数互质的 \(Base\) 和 \(Mod\) \((Base<Mod)\),假设字符串 \(S=s_1s_2s_3……s_n\)
则我们可以定义哈希函数 \(Hash(i)=(c_1\times Base^{i-1} +c_2\times Base^{i-2}+……+c_i\times Base^{0}) \mod Mod\) 来处理前 \(i\) 个字符的哈希值
然后对于 \(Base\) 的次方我们也可以将它存储到一个数组 \(Get[]\) 中,使得 \(Get[i]=Base^{i}\)
\(Tips:\) 使用 unsigned long long
通过它的自然溢出,可以省去哈希函数中取模的一步
以上步骤的代码实现比较容易,如下:
Get[0]=1;
for(int i=1;i<=m;i++) Get[i]=Get[i-1]*base;
for(int i=1;i<=m;i++) val[i]=val[i-1]*b+(uLL)s1[i];
一种高效的数据结构,对于查找的效率几乎等同于常数时间,同时容易实现
多产生的代价仅仅是消耗较多的内存,相当于用空间换取时间
对于哈希函数的构造,可以选择多种方法,比如除余法,乘积法,基数转换法等
为了减小不同的字符串出现相同的哈希值这种误差,可以选择较大的模数,也可以构造多个哈希函数,比较当所有哈希值相同时才判定两个字符串相同
\(STL\) 库中的 \(unordered_map\) 内部就相当于一个哈希表,其存储信息为无序的 \(pair\) 类型,对于不存在的键值赋值时会插入,而已存在的则不会改变,这里不多赘述
这个名字是由发明它的三位学者的名字集合而成的我忘了叫什么了
用来处理字符串匹配问题
通过处理出一个存储下一次从头匹配位置的数组,减少无用匹配的次数,从而优化时间复杂度
具体原理,就是匹配串从第一个字符开始与主串的字符匹配,每匹配一位主串的指针向后移一位,若字符相同则匹配串指针也向后移一位,否则匹配串的指针回到上一个相同字符的位置
没时间了,引例先咕一天
代码实现
Nxt[1]=0;Fir=0;
for(int i=1;i<m;i++){
while(Fir>0&&s2[Fir+1]!=s2[i+1]) Fir=Nxt[Fir];
if(s2[Fir+1]==s2[i+1]) ++Fir;
Nxt[i+1]=Fir;
}//处理 Nxt 数组
Fir=0;
for(int i=0;i<n;i++){
while(Fir>0&&s2[Fir+1]!=s1[i+1]) Fir=Nxt[Fir];
if(s2[Fir+1]==s1[i+1]) ++Fir;
if(Fir==m){ans++;Fir=Nxt[Fir];}
}//统计匹配个数
可以看到预处理 \(Nxt\) 和主程序很像,因为预处理其实也是一个匹配串自我匹配的过程
Power Strings
Seek the Name, Seek the Fame
OKR-Periods of Words
A Horrible Poem
标签:存储 seek 假设 pow 转换 位置 变量 实现 signed
原文地址:https://www.cnblogs.com/KnightL/p/14243674.html