扩展KMP

[C++]洛谷:【模板】扩展 KMP(Z 函数) 算法详解 KMP扩展(Z函数)算法详解,简单易懂! 阅读详情

扩展KMP

  • 什么是扩展KMP

  • 扩展KMP的原理

  • 扩展KMP的编程实现

  • 扩展KMP的用途

参照 ++http://blog.youkuaiyun.com/dyx404514/article/details/41831947++

1 什么是扩展KMP

给出模板串S和T,长度分别为Slen和Tlen,要求在线性时间内,对于每个S[i](0<=i

2 扩展KMP的原理

记母串为S,模式串为T,next[i]表示模式串S的后缀
T[i...len(T)]
与模式串T的最长公共前缀。记为extend[i]为满足
S[i..i+z-1]=T[0..z-1]
的最大的z值,即S串以i开头的后缀与T的最长公共前缀。
2.1 拓展kmp算法一般步骤

首先我们从左到右依次计算extend数组,在某一时刻,设extend[0…k]已经计算完毕,并且之

前匹配过程中所达到的最远位置为P,所谓最远位置,严格来说就是i+extend[i]-1的最大值

(0<=i<=k),并且设取这个最大值的位置为P


S :0......p0.....k k+1......p.......len(s) 现在要计算extend[k+1],根据extend的定义

有S[p0....p] = T[0...p-p0] ——> S[k+1,P] = T[k-p0+1,P-po]

令 len = next[k-p0+1]

(前面介绍了next数组的含义,表示T串与T[k-p0+1,len(T)]的最长公共前缀);

下面通过两种情况讨论:

    1. if k+len < P : 

        S[k+1,k+len] = T[0,len] ——> 则S[k+len+1]一定与T[len]不相等,为什么呢?

        // 因为T[k-p0+1+len] = S[k+1+len],由next数组可知T[k-p0+1+len-1] = T[len-1]

        // T[k-p0+1+len] != T[len] ——> S[k+len+1] !=  T[len] 

        即 extend[k+1] = len

    2. if k + len > p : 

        S[p+1]之后的字符都是未知的,也就是还未进行过匹配的字符串,

        所以在这种情况下,就要从S[P+1]和T[P-k+1]开始一一匹配,直到发生失配为止,

        当匹配完成后,如果得到的extend[k+1]+(k+1)大于P则要更新未知P和p0

    至此,拓展kmp算法的过程已经描述完成

扩展KMP的编程实现

const int maxn=100010;   //字符串长度最大值  
int next[maxn],ex[maxn]; //ex数组即为extend数组  
//预处理计算next数组  
void GETNEXT(char *str)  
{  
    int i = 0,j,po,len=strlen(str);  
    next[0] = len;//初始化next[0]  
    while( str[i] == str[i+1] && i+1 < len)//计算next[1]  
    i++;  
    next[1] = i;  
    po = 1;//初始化po的位置  
    for( i = 2; i < len; i++ )  
    {  
        if( next[i-po]+i < next[po]+po )//第一种情况,可以直接得到next[i]的值  
        next[i] = next[i-po];  
        else//第二种情况,要继续匹配才能得到next[i]的值  
        {  
            j = next[po]+po-i;  
            if( j < 0 )j = 0;//如果i>po+next[po],则要从头开始匹配  
            while( i+j < len && str[j] == str[j+i] )//计算next[i]  
            j++;  
            next[i] = j;  
            po = i;//更新po的位置  
        }  
    }  
}  
//计算extend数组  
void EXKMP(char *s1,char *s2)  
{  
    int i = 0,j,po,len = strlen(s1),l2 = strlen(s2);  
    GETNEXT(s2);//计算子串的next数组  
    while ( s1[i] == s2[i] && i < l2 && i < len )//计算ex[0]  
    i++;  
    ex[0] = i;  
    po = 0;//初始化po的位置  
    for( i = 1; i < len; i++)  
    {  
        if( next[i-po]+i < ex[po]+po )//第一种情况,直接可以得到ex[i]的值  
        ex[i] = next[i-po];  
        else//第二种情况,要继续匹配才能得到ex[i]的值  
        {  
            j = ex[po]+po-i;  
            if( j < 0 ) j = 0;//如果i>ex[po]+po则要从头开始匹配  
            while( i+j < len && j < l2 && s1[j+i] == s2[j] )//计算ex[i]  
            j++;  
            ex[i] = j;  
            po = i;//更新po的位置  
        }  
    }  
}  
扩展KMP(exkmp) exkmpexkmpexkmp 求解的问题:对于给定的主串 SSS ,和模式串 TTT ,求出主串 SSS 的所有后缀与模式串 TTT 的最长公共前缀长度。 KMPKMPKMP 求解的问题是在主串 SSS 中模式串T出现的次数和位置,扩展KMP扩展KMP扩展KMP 求解问题包含了 KMPKMPKMP 求解的问题,因为主串 SSS 中与模式串 TTT 的最长公共前缀长度等于 ∣T∣|T|∣T∣ 的后... 阅读详情

相关推荐

扩展KMP算法(Extend KMP)

扩展kmp既是求模式串和主串的每一个后缀的最长公共前缀 即令s[i]表示主串中以第i个位置为起始的后缀,则B[i]表示s[i]和模式串的最长公共前缀 显然KMP是求s[i]=模式串长度的情况,所以,扩展KMP是对KMP的拓展 像求KMP的next数组一样,我们先求A[i],表示模式串的后缀和模式串的最长公共前缀 然后再利用A[i]求出B[i] 说明一下A的求法,B同理 现在我们要求A[i],且A[1]—A[i-1]已经求出,设k,且1<=k<=i-1,并满足k+A[k]最大 所以T[k]–T[k+A[k]-1]=T[0]–T[A[k]-1],推出T[i]–T[k+A[k]-1]=T[i-k]–

【扩展KMP】【模板】讲解

【扩展KMP】【模板】讲解 摘自 拓展kmp算法总结 1、扩展KMP是什么?解决何种问题?与KMP算法的异同? 拓展kmp是对KMP算法的扩展,它解决如下问题: 定义母串S,和字串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0&amp;amp;amp;lt;=...

Floraqiu的博客 2409

2021-10-29 atcoder ABC157——B - Bingo

B - Bingo 先标记,然后暴力判断,这样最清晰最好想。 #include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; int a[110][110],b[110]; int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>a[i]

honeistbutter的博客 337

扩展KMP算法

如果要用哈希统计从 s 中每一位字符开始最多可以匹配多少位 p 中的字符,需要用到二分查找,此时时间复杂度为Onlogmm,其中 n 表示 s 的长度,m 表示 p 的长度。扩展KMP(也称为Z algorithm)能够以的时间复杂度求出一个字符串 s 和它的任意的的长度。注意其与KMP算法求出的 next 数组的区别,一个是以字符s[i]结束,另一个是从字符s[i]开始。

P0rscher的博客 883

iPhone用户必看:不装App也能搞定GitHub 2FA验证的3种方法(附恢复码管理技巧)

本文为iPhone用户提供了无需安装第三方App即可完成GitHub双重身份验证(2FA)的三种原生方案:利用相机扫码与iCloud钥匙串自动填充、使用iCloud钥匙串内置的TOTP验证码生成器,以及借助Safari浏览器扩展。文章详细解析了每种方法的操作步骤、适用场景,并重点强调了恢复码的安全管理与多层备份策略,帮助开发者在提升账户安全的同时,享受苹果生态的无缝便捷体验。

weixin_29324401的博客 654

[事件相机1]2024CVPR:Event Stream-based Visual Object Tracking: A High-Resolution Benchmark Dataset

作者:Xiao Wang, Shiao Wang, Chuanming Tang, Lin Zhu, Bo Jiang, Yonghong Tian, Jin Tang代码:https://github.com/Event-AHU/EventVOT_Benchmark。

m0_37412775的博客 1706

扩展KMP的应用

FZU-1901 题意:字符串S,问满足S[i] = S[i+P],(i ∈[0,Size -P-1]),升序顺序输出P的取值。 很裸的ex_kmp的定义题!判断Next[j] == Size - j +1 ,以S[j]开头后缀子串是S的一个前缀子串。 /********************************* **...

long1的博客 752

AlphaFold-multimer实战:从零开始预测STAT1-STAT2蛋白复合物结构

本文详细介绍了使用AlphaFold-multimer从零开始预测STAT1-STAT2蛋白复合物结构的完整实战流程。内容涵盖环境配置、数据库准备、序列处理、参数优化及结果可信度评估,为研究者利用这一AI工具进行复合物结构预测提供了系统指南和深度解析。

weixin_29094301的博客 886

KMP+扩展KMP

KMP next数组表示P[j]以前最长相同前缀后缀 若下标从0开始(以下模板就采用这种方式),next[ i ] 表示前面长度为 i 的字符串前缀和后缀相等的最大长度为 next[ i ] 。 若下标从1开始,则next[ i ] 表示前面长度 i - 1的字符串中前缀和后缀相等的最大长度为 next[ i ] - 1 两种方式当S[i]与P[j]不同时j都应该移动到next[j] const ...

UniverseofHK的博客 777

华为eNSP实战:手把手教你配置DHCP全局地址池(含AP固定IP分配)

本文通过华为eNSP模拟器,详细演示了如何配置DHCP全局地址池,为不同业务VLAN动态分配IP地址,并重点讲解了如何通过MAC地址绑定为接入点(AP)分配固定IP。文章涵盖了从拓扑设计、基础网络搭建到地址池精细配置、验证测试及常见故障排查的全流程,是网络工程师掌握企业级DHCP部署与AP管理的实用指南。

weixin_29235923的博客 599

Vue+ECharts-GL 3D地图实战:5层叠加打造炫酷中国地图(附完整代码)

本文详细介绍了如何利用Vue和ECharts-GL构建具有强烈立体感的3D中国地图。通过5层图层的巧妙叠加与样式调校,实现了从背景阴影到交互高光的完整视觉层次,并整合了动态飞线与散点标记。文章提供了完整的代码实现、核心配置解析以及性能优化与视觉调优的实战技巧,帮助开发者快速打造专业级的交互式地图可视化应用。

d6e7f8g9h的博客 649

【模板】kmp以及扩展kmp

kmp算法: 最佳博客: http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html  ; 这里面kmp算法讲的比较详细,我主要在这写下自己的kmp模板以及需要注意的地方。 void getnext(int t) { int i=0,j=-1; while(i!=t) { if(j==-1||a

ten_three 1051

对Palantir的本体论的理解

本体论Ontology是Palantir的整个技术架构的核心与基石,它远不止是一个数据模型,而是一个旨在对企业决策本身进行建模的“数字世界的操作系统”。

liuyukuan的专栏 1147

kmp及扩展kmp

kmp kmp匹配主要匹配的是两个字符串,我们将需要匹配的记录为s1,用于匹配的串为s2. kmp匹配的是从以当前s1中的ch字符为末尾的字符串能够在s2中匹配的最大前缀的长度。 也即是s1中的每个前缀的最长后缀所匹配的s2的最长前缀。 先考虑自身与自身匹配的情况: 如果用dp+数学归纳来思考: 假设当前需要匹配j位置的字符,从0—j-1位置都已经记录了该位置能够匹配到的自身字符...

qq_38890926的博客 261

基于DRU-HVDC的构网型海上风电场环流机理仿真复现

本文介绍了基于DRU-HVDC的构网型海上风电场环流机理仿真模型的构建方法。主要内容包括: 完整的Simulink模型结构,包含主模型文件GFM_DRU_Main.slx和配置脚本GFM_DRU_Setup.m 系统参数设置,包括基础频率(20Hz)、电压基准值(690V)、功率基准值(2MVA)等 四种仿真场景配置:电压不平衡、相位不平衡、阻抗不平衡和频率不平衡 风力发电机(WT)子系统的详细构建步骤,包含电压源、输出阻抗和测量模块 变压器和DRU整流器的参数设置 该模型可用于研究构网型风电场的环流机理。

huanghm88的专栏 262

logisim补码一位乘法器设计.txt

logisim补码一位乘法器设计.txt

扩展kmp

扩展kmp本质还是kmp 有点类似马拉车 就是改变next数组含义为与记录与自身最长的公共前缀的长度(这个也用扩展kmp求) #include<iostream> #include<cstdio> #include<cmath> #include<string.h> #include<cstring> using namespac...

qq_41780519的博客 217

(绝对官方 !绝对官方!可以直接打板!)正点原子 STM32F407 探索者原理图和PCB图

正点原子 STM32F407 探索者原理图和PCB图,绝对官方。1.看清楚了,是原理图和PCB都有。是原理图和PCB!2.可以直接打板卡。

扩展KMP详解

以下摘自http://www.cnblogs.com/yefeng1627/archive/2012/12/24/2830979.html 刘雅琼PPT讲解链接:http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html扩展KMP:     给出模板串A和子串B,长度分别为lenA和lenB,要求在线性时间内,对于每个A[i](0 <= i

静静地码 956

全国各地区-教育139个相关指标(2000-2024年).xlsx

详细介绍及样例数据:https://blog.youkuaiyun.com/T0620514/article/details/156769760

钣金设计工具-jinling钣金展开软件 V1.7 CAD版.exe

钣金设计工具-jinling钣金展开软件 V1.7 CAD版

kmp,manacher,扩展kmp算法总结

考虑到如果有一个位置不符合就从头再来,难免出现浪费,会不会可能出现无需重复比较的情况,那么如果目标子串匹配失败位置的前缀字符串的前缀和后缀有一个最长的匹配长度,首先既然可以来到这个位置,说明前面的字符串肯定完全匹配,那么此时把子串的前缀和母串的后缀对齐再继续比较下一个位置就可以省去了大量比较的时间,其实这就是kmp的本质,但是出现了几个问题,第一,为什么这样跳过一些位置就一定没有错过答案呢,第二,我怎么统计相同的前缀后缀呢,这个过程也并不简单呀,更何况我要统计每个位置的前缀字符串的最长前缀后缀匹配长度。

icebeeeeeef的博客 887

KMP 扩展KMP

1. kmp解决了求所有主串的前缀pre[i] (0 <= i < n)的后缀与模式串前缀的最大匹配长度问题 2. 拓展kmp解决了所有主串的后缀suf[i]的前缀,与模式串前缀的最大匹配长度问题. 3. 当且仅当len%(len-next[len])==0时,str[next[len]~len-1]为最小循环节

YueLing's Blog 530

【黑马计划-1】KMP及扩展KMP

KMP 核心 玄学 failfailfail 数组 failfailfail 数组的含义即是某段字符串的最长公共前后缀。 具体来讲,设 T[1…j−1]=T[i−j…i−1](j⩽i)T[1…j−1]=T[i−j…i−1](j⩽i)T[1\ldots j-1]=T[i-j\ldots i-1](j\leqslant i) ,那么 fail[i]fail[i]fail[i] 为 jjj ...

ezoixx174的博客 4791

KMP与扩展KMP

文章目录KMP扩展KMP KMP 原理看这:原理orz 模板: #include<cstdio> #include<cstring> using namespace std; const int N = 1e6 + 10; int ne[N]; int lt,lp; char a[N],b[N]; void getnext(){ int j = 0,k = -1; ne[0] = -1; while(j < lp){ if(k == -

juruo_c的博客 232

扩展 KMP

目录 扩展 KMP 一:算法流程 二:代码 扩展 KMP 来源 问题定义:给定两个字符串 S 和 T(长度分别为 n 和 m),下标从 0 开始,定义 extend[i] 等于 S[i]... S[n-1] 与 T 的最长相同前缀的长度,求出所有的 ext...

weixin_43410808的博客 134

kmp和扩展kmp code

依据上篇的kmp和扩展kmp原理书写的代码 #include #include #include void Kmp(const char *A, const char *B) { int lenA = strlen(A); int lenB = strlen(B); int *next = (int *)malloc(lenB * sizeof(int));

hyforthy的旅程 859
上一篇: 重温KMP
下一篇: 最近公共祖先(LCA)问题-在线ST算法
code&poetry
博客等级 码龄14年 134粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值