首页 > 其他分享 >kmp & fail树 & border

kmp & fail树 & border

时间:2024-07-22 19:51:03浏览次数:9  
标签:前缀 失配 字符串 kmp fail border

kmp

经典字符串匹配算法。其实是通过找本身前缀\(i\)的最长border,来实现快速匹配的。

这里给出border的定义:字符串\(s\) 的一个子串既是它的前缀又是它的后缀,则这个子串是它的border(一般不包含本身)

kmp通过fail在border上跳,使得每次前面部分的字符串都是相同的,判断新加入的是否匹配即可。

void getkmp(char* s, int n) {
    int p = 0;
    fail[1] = 0;
    for (int i = 2; i <= n; i++) {
        while (p && s[i] != s[p + 1])p = fail[p];
        if (s[i] == s[p + 1])p++;
        fail[i] = p;
    }
}

例题:
luogu: P3375 【模板】KMP
luogu: P4696 [CEOI2011] Matching
这题在线段树&哈希也提到过。这里重新定义kmp的相等,可以实现线性复杂度。

fail树/失配树

注意到kmp的fail数组构成了一个一个树形结构。这个就是失配树。失配树上的所有父亲就是这个前缀的所有border。

P5829 【模板】失配树 中问,字符串\(s\)的\(p\)前缀和\(q\)前缀的最长公共border。即找这个两个节点的\(LCA\)(最近公共祖先)

border

性质(这里的border的起点都指开头):

  • 如果有一个border \(k\)长度大于\(s\)的一半,可以得出得\(s\)有周期 \(|s|−|k|\)
  • 如果 \(p,q\) 都为周期,则 \(gcd(p,q)\)也为周期
    感性理解即可
  • 字符串\(s\)所有不小于\(|s|\)一半的border构成一个等差数列
    \(|s|−|k|\) 是一个周期,每次减少一个周期都是一个新的border。
  • 可以把字符串分成\(log|s|\)段,每一段的border都是一个等差数列
    考虑最后一部分等差数列去掉,\(s\)变成左边一半。这一半的border也成等差数列。最多划分成\(log|s|\)段

重新考虑字符串\(s\)的\(p\)前缀和\(q\)前缀的最长公共border。这次我们直接找到border等差数列的开头。也可以在\(O(nlogn)\)时间复杂度内解决。

例题:
luogu: P5829 【模板】失配树
luogu: P4156 [WC2016] 论战捆竹竿
2021ICPC沈阳站M

标签:前缀,失配,字符串,kmp,fail,border
From: https://www.cnblogs.com/Qing17/p/18316769

相关文章

  • 记录 OpenWrt 执行 opkg update 命令报错 Failed to download,但是换源无效且源用浏览
    记录OpenWrt执行opkgupdate命令报错Failedtodownload,但是换源无效且源用浏览器可访问的解决方案解决方法首先给出解决方法:)网络-->接口-->WAN-->编辑-->高级设置取消勾选“自动获取DNS服务器”-->在使用自定义的DNS服务器一栏中添加并输入可用的DNS地址。......
  • KMP
    做法如何判断一个字符串在另一个字符串里面出现了几次,可以用哈希,不过可能被Hack这里介绍一种总时间\(O(N)\)的写法记\(F(i)\)表示字符串中前缀\([1\)~\(i]\)中最长真前后缀的长度我们可以写出这样一个地推式\(F(i)=\begin{cases}F(i-1)&不是当前字符\\i+1......
  • Error: Assertion failed (nimages > 0) in cv::calibrateCameraRO, file D:\opencv4
    报错信息:Error:Assertionfailed(nimages>0)incv::calibrateCameraRO,fileD:\opencv4\opencv\opencv-4.1.0\modules\calib3d\src\calibration.cpp,line3691  原因:①图片路径问题,没有指向包含棋盘格的图片②图片中不包含棋盘格或者图片模糊等问题,导致查找棋盘......
  • Keil烧录时出现Error: Flash Download failed - “Cortex-M0+“的解决办法
    在对MSPM0L1306mini板使用dapLink烧录例程时,程序能正常编译,但烧录时出现Error:FlashDownloadfailed - "Cortex-M0+"解决办法(同一个方法两种操作)操作1:操作2:两种操作最后打开的页面相同,最后几步操作也相同:点击【OK】保存修改烧录成功......
  • Z 函数(扩展KMP)
    author:LeoJacob,Marcythm,minghu6约定:字符串下标以\(0\)为起点。定义对于一个长度为\(n\)的字符串\(s\),定义函数\(z[i]\)表示\(s\)和\(s[i,n-1]\)(即以\(s[i]\)开头的后缀)的最长公共前缀(LCP)的长度,则\(z\)被称为\(s\)的Z函数。特别地,\(z[0]=0\)。国外一......
  • 扩展 KMP/exKMP(Z 函数)学习笔记
    声明本文章转载自shangruolin的博客,已经过作者(存疑)同意,帮TA宣传一下。扩展KMP/exKMP(Z函数)学习笔记兼P10479匹配统计题解。LCP:最长公共前缀。Z函数,又称扩展KMP(exKMP),能够在\(O(n)\)的时间内求出一个字符串与其所有后缀的LCP的长度。定义\(z_i\)为字符串\(s\)......
  • 猫头虎分享已解决Bug ||Asset validation failed (90296) App sandbox not enabled. T
    ......
  • Doris failed to initialize storage reader. tablet=106408, res=[NOT_IMPLEMENTED_E
    ApacheDoris2.3以下的版本会存在一个bug,导致数据在合并时存在异常,在后续查询该字段数据时会提示[1105][HY000]:errCode=2,detailMessage=(192.168.15.228)[CANCELLED]failedtoinitializestoragereader.tablet=106408,res=[NOT_IMPLEMENTED_ERROR]tobeimplemen......
  • KMP+状态转移
    题目:你现在需要设计一个密码S,S需要满足:S的长度是N;S只包含小写英文字母;S不包含子串T;请问共有多少种不同的密码满足要求?由于答案会非常大,请输出答案模1e9+7的余数。输入格式:第一行输入整数N,表示密码的长度。第二行输入字符串T,T中只包含小写字母。输出格式:输出一个......
  • 2024-07-17 vite打包vue项目,无法正确加载,报错:TypeError: Failed to resolve module sp
    我这会打算打个包扔到线上看看效果,结果线上报错:TypeError:Failedtoresolvemodulespecifier"vue".Relativereferencesmuststartwitheither"/","./",or"../".奇怪,之前还好好的,因为本地调试什么的都正常,甚至昨天都可以打包。我不信邪,遂新建vue项目,做一下测试,这......