从零开始学习字符串算法

前言

字符串算法是OI中非常重要的一个部分,尽管在笔者的印象中NOIP未曾考过,但在省选及NOI甚至更高水平的比赛上几乎逢考必出。

同时,目前在论文、网站、博客、书籍等各类资料上,很少能找到系统而全面地学习一整个知识点的方法和学习过程。

综上,笔者尝试采用一种以时间为轴的全新方式记录从零开始学习字符串算法的整个过程,供读者参考。

笔者认为,学习字符串算法,如果以每天学习6个小时以上来计算,按照本文所述的学习过程,20天可以实现从零到省选水平的质的飞跃。

笔者希望本文能帮助到读者,也期待读者提出宝贵的建议和意见。


Day 0

准备日

前置知识点:C++语言、Hash思想

学习知识点:

第一阶段(8天):字符串Hash、KMP模式匹配算法、Trie(字典树)、AC自动机

第二阶段(12天):马拉车(manacher) 算法、回文自动机、后缀数组、后缀自动机


Day 1

学习:字符串Hash

摘自《算法竞赛进阶指南》(李煜东)

下面介绍的字符串Hash函数把一个任意长度的字符串映射成一个非负整数,并且其冲突的概率几乎为零。

取一固定值\(P\),把字符串看作\(P\)进制数,并分配一个大于\(0\)的数值,代表每种字符。一般来说,我们分配的数值都远小于\(P\)。例如,对于小写字母构成的字符串,可以令\(a=1,b=2,\cdots,z=26\)取一固定值\(M\),求出该\(P\)进制数对\(M\)的余数,作为该字符的Hash值。

一般来说,我们取\(P=131\)\(P=13331\),此时Hash值产生冲突的概率极低,只要Hash值相同,我们就可以认为原字符串是相等的。通常我们取\(M=2^{64}\),即直接使用unsigned long long类型存储这个Hash值,在计算时不处理算术溢出问题,产生溢出时相当于自动对\(2^{64}\)取模,这样可以避免低效的取模(mod)运算。


参考资料

李煜东《算法竞赛进阶指南》(买书地址:京东淘宝

猜你喜欢

转载自www.cnblogs.com/xht37/p/10348532.html