逛ACM神犇的博客的时候看到的这个神奇的算法

KMP吧,失配函数难理解,代码量长

BF吧,慢,很慢,特别慢。

BM吧,我不会写。。。

现在看到了Sunday算法呀,眼前一亮,神清气爽啊。

字符串匹配算法的效率大概是取决于在发生失配时如何进行下一步的问题。

其他咱就不说了。

这个Sunday算法在发生失配的时候,跳过了尽可能多的字符。

  假设在发生不匹配时S[i]≠T[j],1≤i≤N,1≤j≤M。此时已经匹配的部分为u,并假设字符串u的长度为L。如图1。明显的,S[L+i+1]肯定要参加下一轮的匹配,并且T[M]至少要移动到这个位置(即模式串T至少向右移动一个字符的位置)。

1 Sunday算法不匹配的情况

分如下两种情况:
(1) S[L+i+1]在模式串T中没有出现。这个时候模式串T[0]移动到S[L+i+1]之后的字符的位置。如图2。

2 Sunday算法移动的第1种情况

(2)S[L+i+1]在模式串中出现。这里S[L+i+1]从模式串T的右侧,即按T[M-1]、T[M-2]、…T[0]的次序查找。如果发现S[L+i+1]和T中的某个字符相同,则记下这个位置,记为k,1≤k≤M,且T[k]=S[L+i+1]。此时,应该把模式串T向右移动M-k个字符的位置,即移动到T[k]和S[L+i+1]对齐的位置。如图3。

3 Sunday算法移动的第2种情况

依次类推,如果完全匹配了,则匹配成功;否则,再进行下一轮的移动,直到主串S的最右端结束。该算法最坏情况下的时间复杂度为O(N*M)。对于短模式串的匹配问题,该算法执行速度较快。
Sunday算法思想跟BM算法很相似,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。如果该字符没有在匹配串中出现则直接跳过,即移动步长= 匹配串长度+1;否则,同BM算法一样其移动步长=匹配串中最右端的该字符到末尾的距离+1。
 
摘自百度百科
 
再来看个实例
例如我们要在"substring searching algorithm"查找"search",刚开始时,把子
串与文本左边对齐,
substring searching algorithm
search
^
结果在第二个字符处发现不匹配,于是要把子串往后移动。但是该移动多少呢?这
就是各种算法各显神通的地方了,最简单的做法是移动一个字符位置;KMP是利用
已经匹配部分的信息来移动;BM算法是做反向比较,并根据已经匹配的部分来确定
移动量。这里要介绍的方法是看紧跟在当前子串之后的那个字符(上图中的'i'。
显然,不管移动多少,这个字符是肯定要参加下一步的比较的,也就是说,如果下
一步匹配到了,这个字符必须在子串内。所以,可以移动子串,使子串中的最右边
的这个字符与它对齐。现在子串'search'中并不存在'i',则说明可以直接跳过一
大片,从'i'之后的那个字符开始作下一步的比较,如下图:
substring searching algorithm
search
^
比较的结果,第一个字符就不匹配,再看子串后面的那个字符,是'r',它在子串中
出现在倒数第三位,于是把子串向前移动三位,使两个'r'对齐,如下:
substring searching algorithm
  search
这样就匹配完成了 再比如:
匹配串:O U R S T R O N G X S E A R C H
模式串:S E A R C H
这里我们看到O-S不相同,我们就看匹配串中的O在模式串的位置,没有出现在模式串中。
匹配串:O U R S T R O N G X S E A R C H
模式串: _ _ _ _ _ _ _ _S E A R C H
移动模式串,使模式串的首字符和O的下一个字符对齐。
匹配串:O U R S T R O N G X S E A R C H
模式串:_ _ _ _ _ _ _ _ S E A R C H
继续比较,N-S不相同,字符R出现在模式串,则后移模式串,将把它们对齐
匹配串:O U R S T R O N G X S E A R C H
模式串: _ _ _ _ _ _ _ _ _ _ _ S E A R C H
上个代码吧
var s,check:string;
next:array [..] 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:= to do
next[i]:=len_c+;
for i:= to len_c do
next[ord(check[i])-ord('a')]:=len_c-i;
pos:=;
while pos<(len_s-len_c+) do
begin
i:=pos;
for j:= 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(-);
end; begin
readln(s);
readln(check);
writeln(sunday(s,check));
end.

 

Sunday字符串匹配算法的更多相关文章

  1. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

    前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...

  2. Sunday 字符串匹配算法(C++实现)

    简介: Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法.其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹 ...

  3. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  4. Sunday算法:字符串匹配算法进阶

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  5. 字符串匹配算法:Sunday算法

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  6. 字符串匹配算法之Sunday算法(转)

    字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...

  7. Boyer-Moore 字符串匹配算法

    字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...

  8. KMP单模快速字符串匹配算法

    KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...

  9. 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解

    一.前言   在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...

随机推荐

  1. GET方式URL乱码问题解决

      打开 tomcat/conf/server.xml 查找下面这部分,在最后增加一段代码就可以了. <Connector port="80" maxHttpHeaderSi ...

  2. [问题解决] ubuntu server12.04 按ctrl+alt+F1没用

    错误: ubuntu server12.04 想从图形化界面变成命令行界面时候,按ctrl+alt+F1没用 发生场景: 虚拟机下的ubuntu server12.04 解决方案: 因为ctrl+al ...

  3. 这才是正确删除 office 的方式

    https://support.office.com/zh-cn/article/%E9%80%9A%E8%BF%87%E5%9C%A8%E9%87%8D%E6%96%B0%E5%AE%89%E8%A ...

  4. Adobe Acrobat XI Pro 官方下载及安装破解

    Adobe公司推出的PDF 格式是一种全新的电子文档格式.借助 Acrobat ,您几乎可以用便携式文档格式 (Portable Document Format ,简称 PDF) 出版所有的文档. P ...

  5. C语言 linux环境基于socket的简易即时通信程序

    转载请注明出处:http://www.cnblogs.com/kevince/p/3891033.html      ——By Kevince 最近在看linux网络编程相关,现学现卖,就写了一个简易 ...

  6. 美国TJX公司 - MBA智库百科

    美国TJX公司 - MBA智库百科 TJX公司总部设在美国波士顿,在北美地区和许多欧洲国家开有连锁分店,仅在美国就有2500多家分店. TJX Companies, Inc. 是美国和全世界的服装和家 ...

  7. How to Type(dp)

    How to Type Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. [基础]RHEL6下iSCSI客户端挂载配置

    本文根据鸟哥私房菜进行操作:http://linux.vbird.org/linux_enterprise/xen.php?thisscreen=800x600 一.侦测 [root@vhost3 ~ ...

  9. ZOJ1100 状压DP +深搜

    记得做过类似于这类题目是能够用组合数学方法来解决的,可惜淡忘了,也找不到了,看了网上的也有人提到过能够用组合公式解决,但是没人做,都是用了状压DP的方法,这个状压非常难讲清楚吧,推荐两篇 第一遍大体看 ...

  10. jquery数字验证大小比较

    $("#rewardForm").validate({            rules: {                "reward": {       ...