逛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. [转载]CTreeCtrl 和 CListCtrl 控件(VC_MFC)

    来源:http://www.cnblogs.com/kzloser/archive/2012/11/23/2783305.html Tree Control 控件(MSDN 链接) 说明: 树形控件是 ...

  2. Android 多状态按钮 ToggleButton

    ToggleButton      选中状态,未选中状态并且需要为不同的状态设置不同的显示文本.      属性:           checked="true"         ...

  3. c语言中 %p的含义

    格式控制符“%p”中的p是pointer(指针)的缩写.指针的值是语言实现(编译程序)相关的,但几乎所有实现中,指针的值都是一个表示地址空间中某个存储器单元的整数.printf函数族中对于%p一般以十 ...

  4. android ndk jni 环境搭建

    关于ndk jni网上的介绍很多,其实我了解这个主要是因为自己是做嵌入式的,一则是对C语音有感情  二则是知道jni  可以绕过framework 框架直接操作硬件抽象层. 1.概述 对于ndk, j ...

  5. 转: ES6异步编程:Thunk函数的含义与用法

    转: ES6异步编程:Thunk函数的含义与用法 参数的求值策略 Thunk函数早在上个世纪60年代就诞生了. 那时,编程语言刚刚起步,计算机学家还在研究,编译器怎么写比较好.一个争论的焦点是&quo ...

  6. HDU 5809 Ants(KD树+并查集)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5809 [题目大意] 给出一些蚂蚁和他们的巢穴,一开始他们会在自己的巢穴(以二维坐标形式给出),之后 ...

  7. Android切换页面效果的实现一:WebView+ViewFlipper

    前言: 这两周在帮学校做一个新生入学用的“新里程”的项目,要做到页面切换阅读的效果,自己百度了下,找到普遍是使用WebView+ViewFlipper的实现方法,但这种方法不能满足我的要求,因为它很难 ...

  8. [Leetcode][Python]36: Valid Sudoku

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 36: Valid Sudokuhttps://oj.leetcode.com ...

  9. c#搭建服务端 简单中最高效的数据操作Linq (4)

    .NET F 3.5之后提出的linq to sql 概念,大大的简化了对于数据对象的操作,可以通过简单的语法直接操作数据对象,如List,Linq to sql类 等等. 1.使用Linq to s ...

  10. 弹飞DZY(思维,打表,还没过全,先放着)

    弹飞DZYDescription某天,机智的ZZC发明了一种超级弹力装置,为了在他的朋友DZY面前显摆,他邀请DZY一起玩个游戏.游戏一开始,ZZC在地上沿着一条直线摆上n个装置,每个装置设定初始弹力 ...