一.应用:

  同样的,sunday算法也是在一个字符串中查找另一个字符串出现的首地址,是Daniel M.Sunday于1990年提出的,从销量上讲,Sunday>BM>KMP,是这类问题的最优解。在实用上,KMP算法并不比最简单的c库函数strstr()快多少,而BM算法则往往比KMP算法快上3-5倍。

二.核心思想:

  在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率(算法思想很简单)。与BM算法相仿,有点像其删减版,所以其时间复杂度和BM算法差不多,平均性能的 时间复杂度也为O(n),最差情况的时间复杂度为O(n * m),但是要容易理解的多。

  Sunday的算法思想和Horspool有些相似,但是。当出现不匹配的时候,却不是去找匹配串中不匹配的字符在模式串的位置,而是直接找最右边对齐的右一位的那个字符在模式串的位置。

三.算法解析:

  以下面的例子进行具体说明:

源串    :a b  c d  f  h g  e d e w o f d e w o n d e k

匹配串:e w o n  d  e

^

显然,第一个字符不匹配,肯定要把子串往后移动。但是该移动多少呢?对于Sunday来讲,要看的是当前字串后面的那个绿色的 g,判断g是否在匹配串中出现,结论是没有,则说明可以直接跳过一大段,从g之后的字符开始进行比较,得到下图:

源串    :a b  c d  f  h g e d e w o f d e w o n d e k

匹配串:                       e w o n d e

^

在匹配串中,字符’e’出现两次,按照原理,选择最右位置出现的’e’进行对齐,那么可以得到下图:

源串    :a b  c d  f  h g e d e w o f d e w o n d e k

匹配串:       e w o n d e

^

第一个字符就不匹配,我们接下来要观察的则是d,d在匹配串中出现了,将d对齐

源串    :a b  c d  f  h g e d e w o f d e w o n d e k

匹配串:              e w o nd e

^

结果第一个字符就不相等,那么我们要看的依然是当前字符串后面的第一个字符w,这次w在匹配串中出现了,则对齐最右边的w(本例中w只有一个)

源串    :a b  c d  f  h g e d e w o f d e w o n d e k

匹配串:                             e w o n d e

^

在匹配到第四个字符时,f与n不相等,则要考察的是当前字串后面的那个绿色的w,将w对齐,则匹配成功。

源串    :a b  c d  f  h g e d e w o f d e w o n d e k

匹配串:                                            e w o n d e

^

四.代码实现:

因为char是1 个字节,所以我们将数组开到256,char类型最大不能超过256位。

开辟一个有256个元素的数组,用于存放各种字符,下标对应相应字符,如a对应的下标为97,e对应的下标就为101(与ASCII码值对应),该数组里面放的是该字符在匹配串从右向左第一次出现的位置下标。如图:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h> int *GetNext(char *str)
{
int *pNext = NULL;
pNext = (int *)malloc(sizeof(int)*);
memset(pNext,-,sizeof(int)*); //从右向左第一次出现的下标
int i = ;
for(i = ;i<strlen(str);i++)
{
pNext[str[i]] = i;//只需不断赋值就可以保证pnext数组中存入的是最右边的值
}
return pNext;
} int Sunday(char *src,char *match)
{
if(src == NULL || match == NULL)return -; //获得next数组
int *pNext = NULL;
pNext = GetNext(match); int i; //遍历主串
int j; //遍历匹配串的
int k; //每一次进行匹配时,匹配串的头在源串中对应的位置(每一次匹配的开始位置,红色字母) i = ;
j = ; while(i < strlen(src) && j < strlen(match))
{
k = i;//随着匹配向后进行,不断更新每次匹配的开始位置
while(src[i] == match[j])
{
i++;
j++;
}
if(j == strlen(match))
{
return i-j;
}
else
{  //实现对齐
//k+strlen(match):找到主串对应匹配串的下一位置(对应图解中的绿色字符)
//pnext[src[k+strlen(match)]]找到当前字符在匹配串中第一次出现的下标,相减
i = k+strlen(match) - pNext[src[k+strlen(match)]];//表面是相同字符对齐,实际上确定了新的起始位置
j = 0;
}
}
return -;
} int main()
{
int n;
n = Sunday("abcabcdabcabceabcabcdabcabcadshfoiewr","abcabcdabcabca");
printf("%d\n",n);
return ;
}

Sunday算法[原创]的更多相关文章

  1. 文本比较算法三——SUNDAY 算法

    SUNDAY 算法描述: 字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上 ...

  2. 字符串匹配的sunday算法

    sunday算法核心思想:启发式移动搜索步长! SUNDAY 算法描述: 字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).这里介 ...

  3. Sunday算法(字符串查找、匹配)

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

  4. 字符串模式匹配sunday算法

    文字部分转自:http://www.cnblogs.com/mr-ghostaqi/p/4285868.html 代码是我自己写的 今天在做LeetCode的时候,碰到一个写字符串匹配的题目: htt ...

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

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

  6. sunday算法实现

    这个算法比其他的kmp  bm 好理解的太多,而且速度还很快. sunday思路是: 1,Sunday算法是Daniel M.Sunday于1990年提出的一种比BM算法搜索速度更快的算法.  2,S ...

  7. BF、KMP、BM、Sunday算法讲解

    BF.KMP.BM.Sunday算法讲解 字串的定位操作通常称作串的模式匹配,是各种串处理系统中最重要的操作之一. 事实上也就是从一个母串中查找一模板串,判定是否存在. 现给出四种匹配算法包括BF(即 ...

  8. 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)

    字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...

  9. 数据结构 Sunday算法

    Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配算法.相对比较KMP和BM算法而言,简单了许多. Sunday算法的思想类似于BM算法中的坏字符思想,有点像其删减版.差 ...

随机推荐

  1. 网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析

    网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析 CPM CPT CPC CPA CPS SEM SEO在网络营销中是什么意思?SEO和SEM的区别是? CPM(Cost ...

  2. API和正则表达式

    第一章 String & StringBuilderString类用类final修饰,不能被继承,String字符串被创建后永远无法被改变,但字符串引用可以重新赋值,改变引用的指向java字符 ...

  3. Linux 系统版本信息

    1.# uname -a   (Linux查看版本当前操作系统内核信息) 2.# cat /proc/version (Linux查看当前操作系统版本信息) 3.# cat /etc/issue  或 ...

  4. .net Core 中将原MVC中的 MvcHtmlString转换

    public static IHtmlContent CustomLabelFor<TModel, TProperty>(this IHtmlHelper helper, Expressi ...

  5. CF#235E. Number Challenge

    传送门 可以理解为上一道题的扩展板.. 然后我们就可以YY出这样一个式子 ${\sum_{i=1}^a\sum_{j=1}^b\sum_{k=1}^cd(ijk)=\sum_{i=1}^a\sum_{ ...

  6. c++builder ZIP文件解压与压缩(ZLIB DLL调用)(转载 )

    转载:http://blog.csdn.net/goodai007/article/details/7414512 头文件:ZipAndFile.h //----------------------- ...

  7. tcp网络通信的三次握手与三次挥手

    背景描述 通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在 ...

  8. IntelliJ IDEA 连接数据库 详细过程

    IntelliJ IDEA集成了众多插件,方便开发者使用,使用其自带的Database模块就可以很方便的配置.连接到数据库,本次操作以MySQL为例,其中testjdbc数据库已经提前建好,里面有两张 ...

  9. jQuery:ajax处理html页面

    源码: $.ajax({ url: url, success: function (data) { var reg = /<body>[\s\S]*<\/body>/g; ]; ...

  10. attr返回被选元素的属性值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...