标签:style blog http io color ar os for sp
逛ACM神犇的博客的时候看到的这个神奇的算法
KMP吧,失配函数难理解,代码量长
BF吧,慢,很慢,特别慢。
BM吧,我不会写。。。
现在看到了Sunday算法呀,眼前一亮,神清气爽啊。
字符串匹配算法的效率大概是取决于在发生失配时如何进行下一步的问题。
其他咱就不说了。
这个Sunday算法在发生失配的时候,跳过了尽可能多的字符。
例如我们要在"substring searching algorithm"查找"search",刚开始时,把子
串与文本左边对齐,
substring searching algorithm
search
^
结果在第二个字符处发现不匹配,于是要把子串往后移动。但是该移动多少呢?这
就是各种算法各显神通的地方了,最简单的做法是移动一个字符位置;KMP是利用
已经匹配部分的信息来移动;BM算法是做反向比较,并根据已经匹配的部分来确定
移动量。这里要介绍的方法是看紧跟在当前子串之后的那个字符(上图中的‘i‘。
显然,不管移动多少,这个字符是肯定要参加下一步的比较的,也就是说,如果下
一步匹配到了,这个字符必须在子串内。所以,可以移动子串,使子串中的最右边
的这个字符与它对齐。现在子串‘search‘中并不存在‘i‘,则说明可以直接跳过一
大片,从‘i‘之后的那个字符开始作下一步的比较,如下图:
substring searching algorithm
search
^
比较的结果,第一个字符就不匹配,再看子串后面的那个字符,是‘r‘,它在子串中
出现在倒数第三位,于是把子串向前移动三位,使两个‘r‘对齐,如下:
substring searching algorithm
search
这样就匹配完成了
再比如:
上个代码吧
var s,check:string; next:array [0..26] of longint; function sunday(s,check:string):longint; var len_s,len_c,i,pos,j:longint; begin len_s:=length(s); len_c:=length(check); for i:=1 to 26 do next[i]:=len_c+1; for i:=1 to len_c do next[ord(check[i])-ord(‘a‘)]:=len_c-i; pos:=1; while pos<(len_s-len_c+1) do begin i:=pos; for j:=1 to len_c do begin if s[i]<>check[j] then begin inc(pos,next[ord(s[pos+len_c])-ord(‘a‘)]); break; end; inc(i); end; if j=len_c then exit(pos); end; exit(-1); end; begin readln(s); readln(check); writeln(sunday(s,check)); end.
标签:style blog http io color ar os for sp
原文地址:http://www.cnblogs.com/logichandsome/p/4077793.html