一.应用:

  同样的,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. mysql分类和事务回滚

    主要内容: ***数据定义语言DDL重点 ***数据操纵语言DML重点 数据查询语言DQL重点 ---事务控制语言TCL ---数据库控制语言DCL ---主键(primary key) ---数据冗 ...

  2. Python Web学习笔记之并发编程的孤儿进程与僵尸进程

    1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两个概念比较模糊.今天被人问到什么是孤儿进程和僵尸进程,会带来什么问题,怎么解决,我只停留在概念上 ...

  3. Mysql截取和拆分字符串函数用法

    Mysql截取和拆分字符串函数用法 截取字符串函数: SUBSTRING(commentid,9) 意思是:从第9个字符开始截取到最后.SUBSTRING的参数有三个,最后一个是截取的长度,默认是到结 ...

  4. JavaScript 读取修改元素 及 伸拉门案例

    JavaScript 读取修改元素 及 伸拉门案例 版权声明:未经授权,严禁转载! 读取 / 修改元素 - 读取修改元素内容 - 读取修改元素属性 - 读取修改元素样式 元素的内容 读取或修改元素节点 ...

  5. PHP 验证码:扭曲+粘连+变形

    一,绪论 由于项目需要,需要加强目前的验证码,我们参照的对象是支付宝. 基于PHP CodeIgniter 框架,代码放置在下面的路径下. /application/libraries 二,主要代码 ...

  6. 《网络对抗》拓展:注入shellcode

    实践三 知识要求: shellcode:指溢出后执行的能开启系统shell的代码.但是在缓冲区溢出攻击时,也可以将整个触发缓冲区溢出攻击过程的代码统称为shellcode,因此可以将shellcode ...

  7. Socket:读写处理及连接断开的检测

    作为进程间通信及网络通信的一种重要技术,在实际的开发中,socket编程是经常被用到的.关于socket编程的一般步骤,这里不再赘述,相关资料和文章很多,google/baidu即可. 本文主要是探讨 ...

  8. 网络安全、Web安全、渗透测试之笔经面经总结(三)

    本篇文章涉及的知识点有如下几方面: 1.什么是WebShell? 2.什么是网络钓鱼? 3.你获取网络安全知识途径有哪些? 4.什么是CC攻击? 5.Web服务器被入侵后,怎样进行排查? 6.dll文 ...

  9. Python3基础 try-except-finally 的简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. Python3基础 file with 配合文件操作

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...