没有合适的资源?快使用搜索试试~ 我知道了~
首页串匹配算法——kmp算法,并行算法
串匹配(String Matching)问题是计算机科学中的一个基本问题,也是复杂性理论中研究的最广泛的问题之一。它在文字编辑处理、图像处理、文献检索、自然语言识别、生物学等领域有着广泛的应用。而且,串匹配是这些应用中最耗时的核心问题,好的串匹配算法能显著地提高应用的效率。因此,研究并设计快速的串匹配算法具有重要的理论价值和实际意义。 串匹配问题实际上就是一种模式匹配问题,即在给定的文本串中找出与模式串匹配的子串的起始位置。最基本的串匹配问题是关键词匹配(Keyword Matching)。所谓关键词匹配,是指给定一个长为n的文本串T[1,n]和长为m的模式串P[1,m],找出文本串T中与模式串所有精确匹配的子串的起始位置。串匹配问题包括精确串匹配(Perfect String Matching)、随机串匹配(Randomized String Matching)和近似串匹配(Approximate String Matching)。另外还有多维串匹配(Multidimensional String Matching)和硬件串匹配(Hardware String Matching)等。 本章中分别介绍改进的KMP串匹配算法,采用散列技术的随机串匹配算法,基于过滤算法的近似串匹配算法,以及它们的MPI编程实现。
资源详情
资源评论
资源推荐

1. 2 串匹配
串匹配(String Matching)问题是计算机科学中的一个基本问题,也是复杂性理论中研
究的最广泛的问题之一。它在文字编辑处理、图像处理、文献检索、自然语言识别、生物
学等领域有着广泛的应用。而且,串匹配是这些应用中最耗时的核心问题,好的串匹配算
法能显著地提高应用的效率。因此,研究并设计快速的串匹配算法具有重要的理论价值和
实际意义。
串匹配问题实际上就是一种模式匹配问题,即在给定的文本串中找出与模式串匹配的
子串的起始位置。最基本的串匹配问题是关键词匹配(Keyword Matching)。所谓关键词匹
配,是指给定一个长为 n 的文本串 T[1,n]和长为 m 的模式串 P[1,m],找出文本串 T 中与
模式串所有精确匹配的子串的起始位置。串匹配问题包括 精确串匹配(Perfect String
Matching)、 随机串匹配(Randomized String Matching )和近似串匹配(Approximate
String Matching)。另外还有 多维串匹配(Multidimensional String Matching)和硬件串匹
配(Hardware String Matching)等。
本章中分别介绍改进的 KMP 串匹配算法,采用散列技术的随机串匹配算法,基于过
滤算法的近似串匹配算法,以及它们的 MPI 编程实现。
1.1 KMP 串匹配算法
1.1.1 KMP 串匹配及其串行算法
KMP 算法首先是由 D.E. Knuth、J.H. Morris 以及 V.R. Pratt 分别设计出来的,所以该算
法被命名为 KMP 算法。KMP 串匹配算的基本思想是:对给出的的文本串 T[1,n]与模
式串 P[1,m],假设在模式匹配的进程中,执行 T[i]和 P[j]的匹配检查。 若 T[i]=P[j],则继
续检查 T[i+1]和 P[j+1]是否匹配。若 T[i]≠P[j],则分成两种情况:若 j=1,则模式串右移一
位,检查 T[i+1]和 P[1]是否匹配;若 1<j≤m,则模式串右移 j-next(j)位,检查 T[i]和
P[next(j)]是否匹配(其中 next 是根据模式串 P[1,m]的本身局部匹配的信息构造而成的)。
重复此过程直到 j=m 或 i=n 结束。
1. 修改的 KMP 算法
在原算法基础上很多学者作了一些改进工作,其中之一就是重新定义了 KMP 算法中
的 next 函数,即求 next 函数时不但要求 P[1,next(j) -1]=P[j-(next(j) -1),j-1],而且要
求 P[next(j)] ≠P[j],记修改后的 next 函数为 newnext。在模式串字符重复高的情况下修改
的 KMP 算法比传统 KMP 算法更加有效。
算法 14.1 修改的 KMP 串匹配算法
输入:文本串 T[1,n]和模式串 P[1,m]
输出:是否存在匹配位置
procedure modeifed_KMP
1

Begin
(1) i=1,j=1
(2) while i≤n do
(2.1)while j≠0 and P[j]≠T[i] do
j=newnext[j]
end while
(2.2)if j=m then
return true
else
j=j+1,i=i+1
end if
end while
(3) return false
End
算法 14.2 next 函数和 newnext 函数的计算算法
输入:模式串 P[1,m]
输出:next[1,m+1]和 newnext[1,m]
procedure next
Begin
(1) next[1]=0
(2) j=2
(3) while j≤m do
(3.1)i=next[j-1]
(3.2)while i≠0 and P[i]≠P[j-1] do
i=next[i]
end while
(3.3)next[j]=i+1
(3.4)j=j+1
end while
End
procedure newnext
Begin
(1) newnext(1)=0
(2) j=2
(3) while j≤m do
(3.1)i=next(j)
(3.2)if i=0 or P[j]≠P[i+1] then
newnext[j]=i
else
newnext[j]=newnext[i]
end if
(3.3)j=j+1
2

end while
End
2. 改进的 KMP 算法
易知算法 14.1 的时间复杂度为 O(n),算法 14.2 的时间复杂度为 O(m)。算法
14.1 中所给出的 KMP 算法只能找到第一个匹配位置,实际应用中往往需要找出所有的匹配
位置。下面给出改进后的算法 14.3 便解决了这一问题。
算法 14.3 改进 KMP 串匹配算法
输入:文本串 T[1,n]和模式串 P[1,m]
输出:匹配结果 match[1,n]
procedure improved_KMP
Begin
(1) i=1,j=1
(2) while i≤n do
(2.1)while j≠0 and P[j]≠T[i] do
j=newnext[j]
end while
(2.2)if j=m then
match[i-(m-1)]=1
j=next[m+1]
i=i+1
else
i=i+1
j=j+1
end if
end while
(3) max_prefix_len=j-1
End
算法 14.4 next 函数和 newnext 函数的计算算法
输入:模式串 P[1,m]
输出:next[1,m+1]和 newnext[1,m]
procedure NEXT
Begin
(1) next[1]=newnext[1]=0
(2) j=2
(3) while j≤m+1 do
(3.1)i=next[j-1]
(3.2)while i≠0 and W[i]≠W[j-1]) do
i=next[i]
end while
(3.3)next[j]=i+1
(3.4)if j≠m+1 then
3

if W[j] ≠W[i+1] then
newnext[j]=i+1
else
newnext[j]=newnext[i+1]
end if
end if
(3.5)j=j+1
end while
End
在算法 14.3 中,内层 while 循环遇到成功比较时和找到文本串中模式串的一个匹配位
置时文本串指针 i 均加 1,所以至多做 n 次比较;内 while 循环每次不成功比较时文本串指
针 i 保持不变,但是模式串指针 j 减小,所以 i-j 的值增加且上一次出内循环时的 i-j 值等
于下一次进入时的值,因此不成功的比较次数不大于 i-j 的值的增加值,即小于 n,所以
总的比较次数小于 2n,所以算法 14.3 的时间复杂度为 O(n)。算法 14.4 只比的算法 14.2
多 计 算 了 next(m+1) , 至 多 多 做 m-1 次 比 较 , 所 以 算 法 14.4 的 时 间 复 杂 度 同 样 为
O(m)。
1.1.2 KMP 串匹配的并行算法
1. 算法原理
在介绍了改进的 KMP 串行算法基础上,这一节主要介绍如何在分布存储环境中对它进
行实现。设计的思路为:将长为 n 的文本串 T 均匀划分成互不重叠的 p 段,分布于处理器 0
到 p-1 中,且使得相邻的文本段分布在相邻的处理器中,显然每个处理器中局部文本段的
长度为 (最后一个处理器可在其段尾补上其它特殊字符使其长度与其它相同)。再
将长为 m 的模式串 P 和模式串的 newnext 函数播送到各处理器中。各处理器使用改进的
KMP 算法并行地对局部文本段进行匹配,找到所有段内匹配位置。
但是每个局部段(第 p-1 段除外)段尾 m-1 字符中的匹配位置必须跨段才能找到。一
个简单易行的办法就是每个处理器(处理器 p-1 除外)将本局部段的段尾 m-1 个字符传送
给下一处理器,下一处理器接收到前一处理器传来的字符串后,再接合本段的段首 m-1 个
字符构成一长为 2(m-1)的段间字符串,对此字符串做匹配,就能找到所有段间匹配位置。
但是算法的通信量很大,采用下述两种改进通信的方法可以大大地降低通信复杂度:①降
低播送模式串和 newnext 函数的通信复杂度。利用串的周期性质,先对模式串 P 作预处理,
获得其最小周期长度|U|、最小周期个数 s 及后缀长度|V|(P=U
s
V),只需播送 U,s,|V|
和部分 newnext 函数就可以了,从而大大减少了播送模式串和 newnext 函数的通信量。而
且串的最小周期和 next 函数之间的关系存在着下面定理 1 所示的简单规律,使得能够设计
出常数时间复杂度的串周期分析算法。②降低每个处理器(处理器 p-1 除外)将本局部文
本段的段尾 m-1 个字符传送给下一处理器的通信复杂度。每个处理器在其段尾 m-1 个字符
中找到模式串 P 的最长前缀串,因为每个处理器上都有模式串信息,所以只需传送该最长
前缀串的长度就行了。这样就把通信量从传送模式串 P 的最长前缀串降低到传送一个整数,
从而大大地降低了通信复杂度。而且 KMP 算法结束时模式串指针 j-1 的值就是文本串尾模
式串最大前缀串的长度,这就可以在不增加时间复杂度的情况下找到此最大前缀串的长度
4

2. 串的周期性分析
定义 14.1:给定串 P,如果存在字符串 U 以及正整数 K≥2,使得串 P 是串 U
k
的前缀
(Prefix),则称字符串 U 为串 P 的周期(Period)。字符串 P 的所有周期中长度最短的
周期称为串 P 的最小周期(Miximal Period)。
串的周期分析对最终并行算法设计非常关键,串的最小周期和 next 函数之间的关系存
在着如下定理 14.1 所示的简单规律,基于该规律可以设计出常数时间复杂度的串周期分析
算法。
定理 14.1:已知串 P 长为 m,则 u=m+1-next(m+1)为串 P 的最小周期长度。
算法 14.5 串周期分析算法
输入:next[m+1]
输出:最小周期长度 period_len
最小周期个数 period_num
模式串的后缀长度 pattern-suffixlen
procedure PERIOD_ANALYSIS
Begin
period_len=m+1-next(m+1)
period_num=(int)m/period_len
pattern_suffixlen=m mod period_len
End
3. 并行算法描述
在前述的串行算法以及对其并行实现计的分析的基础上,我们可以设计如下的并行
KMP 串匹配算法。
算法 14.6 并行 KMP 串匹配算法
输入:分布存储的文本串 T
i
[1, ](i=0,1,2,…,p-1)
存储于 P
0
的模式串 P[1,m]
输出:所有的匹配位置
Begin
(1) P
0
call procedure NEXT /*调用算法 14.4,求模式串 P 的
next 函数和 newnext 函数*/
P
0
call procedure PERIOD_ANALYSIS /*调用算法 14.5 分析 P 的周期*/
(2) P
0
broadcast period_len,period_num,period_suffixlen to other processors /*播送
P 之最小周期长度、最小周期个数和后缀长度*/
P
0
broadcast P[1,period_len] /*不播送 P 之最小周期*/
if period_num=1 then /*播送 P 之部分 newnext 函数,如周期为 1,则播送整个
newnext 函数;否则播送 2 倍周期长的 newnext 函数*/
broadcast newnext [1,m]
else
broadcast newnext[1,2*period_len]
end if
(3) for i=1 to p-1 par-do /*由传送来的 P 之周期和部分 newnext 函数重构整个模式串
和 newnext 函数*/
P
i
rebuild newnext
5
剩余21页未读,继续阅读


















安全验证
文档复制为VIP权益,开通VIP直接复制

评论4