一.应用:

  同样的,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. org.apache.catalina.core.StandardWrapperValve invoke的解决办法

    org.apache.catalina.core.StandardWrapperValve invoke的解决办法 比较容易错的地方是页面带参数进行跳转,由于跳转之后的页面本身也要执行一部分sql语句 ...

  2. mysql合并 两个count语句一次性输出结果的方法

    mysql合并 两个count语句一次性输出结果的方法 需求场景:经常要查看有两个表统计数,用SELECT COUNT(*) FROM hotcontents,SELECT COUNT(*) FROM ...

  3. 一个快速检测系统CPU负载的小程序

    原理说明 在对服务器进行维护时,有时也遇到由于系统 CPU(利用率)负载过高导致业务中断的情况.服务器上可能运行多个进程,查看单个进程的 CPU 都是正常的,但是整个系统的 CPU 负载可能是异常的. ...

  4. Eclipse启动Tomcat时,45秒超时解决方式

    Eclipse启动Tomcat时,45秒超时解决方式 在Eclipse中启动Tomcat服务器时,经常由于系统初始化项目多,导致出现45秒超时的Tomcat服务器启动错误.  一般通过找到XML配置文 ...

  5. centos下gitlab私服完整安装部署(nginx+MySQL+redis+gitlab-ce+gitlab-shell+)

    系统环境cat /etc/redhat-release CentOS release 6.8 (Final) nginx -vnginx version: nginx/1.9.15 redis-cli ...

  6. Memcached深入分析及内存调优

    到这里memcached的初步使用我们已经没问题了,但是了解一些它内部的机制还是十分必要的,这直接涉及到你能否把memcached给真正“用好”. Memcached的守护进程机制使用的是Unix下的 ...

  7. Eclipse给方法或者类添加自动注释

    自动生成注释: 在团队开发中,注释是必不可少的,为了是自己的注释看起来更加优雅,注释的格式应该统一,我们可以使用Eclipse注释模板自动生成注释. 具体操作如下: 打开注释模板编辑窗口:Window ...

  8. JavaScript 开闭原则OCP

    代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...

  9. Win7系统中如何查看当前文件被哪一个程序占用了

    https://superuser.com/questions/117902/find-out-which-process-is-locking-a-file-or-folder-in-windows ...

  10. 如何在windows中部署Gitblit

    1.安装Java环境 2.下载Gitblit压缩包 http://gitblit.com/ 3.解压后进行配置 编辑gitblit-1.8.0\data\gitblit.properties文件 gi ...