数据结构--串

串名、串值、串长、空串、空格串。


字符串的比较


字符串模式匹配算法:

1. 简单字符串模式匹配算法

最简单实现是用字符串P的字符依次与字符串T中的字符进行比较。实现思想是,首先将子串P从第0个字符起与主串T的第pos个字符起依次比较对应字符,如全部对应相等,则表明已找到匹配,成功终止。否则将子串P从第0个子串起与主串T的第pos+1个字符起依次比较字符。如此进行,直到某次成功匹配。或某次T中无足够的剩余字符与P中个字符匹配失败为止。


2. 首尾字符串模式匹配算法

为了避免在每趟匹配的最后一个字符时才发现不能匹配,可采用从模式串的两头分别比较的方法,先比较模式串的第0个字符,再比较模式串的最后一个字符,然后才依次比较第一个到第N个。


3. KMP字符串模式匹配算法

上述两种算法效率低,原因是执行过程有回溯。

普通的字符串模式匹配算法上,当遇到主串和模式串的字符不能匹配成功时,不论已经匹配了多少字符都要进行指针回溯,再开始下一轮的匹配。这样效率是十分的低下的。KMP算法,是在朴素的模式匹配算法的基础上,实现了匹配不成功时,不对主串指针进行回溯,使模式匹配的时间复杂度降低为:O(n + m)。

KMP算法的核心思想是,在s[i] 和 p[j]不匹配时,不对主串进行指针回溯,而是在模式串中p中寻找k,用s[i] 和 p[k]进行下一轮的匹配。

在这里,将主串 S 和模式串 P 都看成是一条直线,故而在S[i] 和 P[j] 匹配不成共时,有如下情形:

image 

图1 s[i] 和 p[j] 匹配不成功

即是:p[1…j-1] == s[i-j+1,…,i-1].

p[j] 和 s[i] 不匹配,现在要在模式串p[1,…,j-1]确定一个位置k(1<= k < j-1),用p[k]和s[i]进行下一轮匹配,那么k必须要满足以下条件:

p[1,..,k-1] == s[i-k+1, … , i-1] .

将模式串和主串都看着一条直线,那么就有下图:

image

图2  使用p[k]和s[i]进行下一轮匹配

由于 1<= k < j-1,那么将两图合并起来会有什么效果呢?

image

从上图可以看出,当s[i]和p[j]匹配不成功时,假如能用p[k]和s[i]进行下一轮匹配,则有:

s[i-k+1], … , i-1] == p[j-k+1,…,j-1] == p[1,…,k-1] 。

就是说,当s[i] 和 p[j] 匹配不成功时,最对主串不进行指针回溯,而是用p[k]和s[i]进行匹配时,k必须满足以下条件:

p[1,…,k-1] == p[j-k+1, … , j-1]。

  • KMP算法的实现

KMP算法的是对匹配的模式匹配算法的改进,在s[i]和p[j]匹配不成功时,不是对主串进行指针的回溯,而是在p[1,…,j-1]中,寻找一个p[k],

用s[i]和p[k]进行下一轮的匹配。其实现的最大问题就是如何的根据p[1,…,j-1]来求出p[k]。

在KMP算法的实现中,使用一个辅助数组next[],使用该数组保存p[j]匹配不成功时,要进行下一轮匹配的k的值.即是当s[i] 和 p[j]匹配不成功时,

用p[ next[j] ]来和s[i]进行下一轮匹配,k = next[j] .

对数组next[] 的求解,可以goolge到不少的方法,这里使用最简单的递推的方法:

首先假定next[0] = –1,那么当next[j] = k时,就有:p[0,…,j-1] == p[j-k+1,…,j-1]。

这时,若有p[k] = p[j] ,则p[0,….,k] = p[j-k+1,..,j-1,j],从而就有next[j+1] = next[j] + 1 = k +1 .

若p[k] != p[j] ,可以看着模式串对自身进行匹配的问题,即当匹配失败的时候,k值如何确定,k = next [k] .


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值