模式匹配,子字符串的判断与位置确定,KMP算法的理解

子字符串的判断与位置确定,KMP算法的理解

给定字符串 s 和 t , s 是否为 t 的子字符串,若是则给出s在t中的首项位置。
例:t=BBC_ABCDAB_ABCDABCDABDE
S=ABCDABD 长度为7(例如,"bcd"是"abcde"的一个子字符串,而"aec"不是)

这个问题可以直接暴力解决,先从t[0]开始挨个比较s,然后在从t[1]…开始。

第二种解法是KMP算法:

在理解这个算法时遇到了些困难,在这里自己在梳理一下,
算法基本思想是从t[q]开始依次和s比较,假设s长度为ns,然后发现 t[q]-t[k+q-1]=s[0]-s[k-1];(其中k<ns);

就好比下面这个例子:
BBC_ABCDAB_ABCDABCDABDEABCDABD

这时s[0]–s[5]都已在t中找到匹配项,但s[6]确和t中的下一位不相同,按照暴力解法,这时我们从本次比较中t的起始点往后顺移一位作起始点,然后在依次比较过去。

但我们发现(假设本次比较t从t[r]开始)我们已知t[r]-t[k+r-1]=s[0]-s[k-1] ,也就是说此时我们已经知道t[r+1]-t[k+r-1]=s[1]-s[k-1];暴力解法从t[r+1]开始,依次和s比较,如果比较成功,则说明t[r+1]-t[k+r-1]=s[0]-s[k-2];再结合t[r+1]-t[k+r-1]=s[1]-s[k-1],则必有s[1]-s[k-1]=s[0]-s[k-2],反之也就是说如若s[1]-s[k-1]=s[0]-s[k-2]不成立,则t从t[r+1]开始必不成功。问题也就转化为在已经匹配成功的s[0]-s[k-1]中,寻找一个下标h其中(h<k-1),使得s[0]-s[h]=s[k-h-1]-s[k-1],然后s从s[h+1]开始,t从t[k+r]开始接着依次比较是否和s相同,这样就避免了对t的无用的重复的讨论。但这里就有一个问题是如何找到这个h使得在S[0]-s[k-1]中s[0]-s[h]=s[k-h-1]-s[k-1],也就是转化为在一个字符数组中寻找个下标使得“头尾重合”。先假设有这么一个函数Find(形参为字符串数组),也就是kmp中的fail函数(手动滑稽)。那么这个问题代码为:

int Kfind(string s, string t) {
   
	int ns = s.size();	
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值