文字部分转自:http://www.cnblogs.com/mr-ghostaqi/p/4285868.html

代码是我自己写的

今天在做LeetCode的时候,碰到一个写字符串匹配的题目:

https://oj.leetcode.com/problems/implement-strstr/

我一看就懵了,字符串模式匹配我记得当时在上数据结构的时候,书上只写了BF和KMP算法,老师说考试“只可能会考BF”,KMP不要求掌握。

然后出于一颗探求的心,我还是看了一下KMP,这算法好难理解,于是就没记下来。

一看这题就跪了。

上网查了一些算法,好像都对sunday算法很推崇的样子,于是找了好几个看了看,算法思想挺简单的,数学证明我也懒得去了解,毕竟我也不是学数学的料。

算法的基本思想是,模式串和主串从后往前比较,遇到无法匹配的字符的时候,看主串参加匹配的最后一个字符的下一个字符,然后分两种情况:

1、如果该字符没有出现在模式串中,就把模式串向右移动模式串的长度+1个位置。

比如:主串:  ababcdababa

模式串:ababa

到c的位置无法匹配,看c后面的d没有出现在模式串中,则向右移动5+1个位置,结果为:

主串:  ababcdababa

模式串:      ababa

也就是说移动到d后面的一个字符。

2、如果该字符出现在模式串中,则向右移动“该字符在模式串中出现的最右边那次”到字符串末尾的长度+1。

比如:主串:  ababcababa

模式串:ababa

到c的位置无法匹配,看c后面的a出现在模式串中,而模式串中有3个a,我们看最右边那个a,则向右移动0+1个位置,结果为:

主串:  ababcababa

模式串: ababa

 #include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#define maxn 100100
#define N 22000
using namespace std;
int dis[];
char *strStr(char *haystack, char *needle)
{
//haystack 表示母串
// needle 表示子串
int slen = strlen(haystack);
int plen = strlen(needle); int dis[];// 表示当不匹配时跳过的距离 for(int i = ; i < ;i++)
{
dis[i] = plen+;// 初始化为子串长度+1 } for(int i = ; i < plen;i++)
{
dis[needle[i] - 'a'] = plen - i;
} int s = ;
int i = s;
int j = ; while(i < slen&&j < plen)
{
if(haystack[i] == needle[j])
{
i++;
j++;
}
else
{
if(s + plen < slen)// 要判断 s + plen那个一个元素是否存在
{
char c = haystack[s+plen];
s = s + dis[c - 'a'];
i = s;
j = ;
}
else
{
return NULL;
}
}
} if(j == plen)return haystack+s;
else return NULL; }
int main()
{
char* str = "a";
char* p = "a";
char* q = NULL;
q = strStr(str,p); if(q == NULL)puts("NO");
if(q!=NULL)printf("%s\n",q); }
 #include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#define maxn 100100
#define N 22000
using namespace std;
int dis[];
//返回出现的第一个位置,否则返回NULL
char *sunday(char *haystack, char *needle)
{
//haystack 表示母串
// needle 表示子串
int slen = strlen(haystack);
int plen = strlen(needle); int dis[];// 表示当不匹配时跳过的距离 for(int i = ; i < ;i++)
{
dis[i] = plen+;// 初始化为子串长度+1 }
for(int i = ; i < plen;i++)
{
dis[needle[i] - 'a'] = plen - i;
} int s = ;
int i = s;
int j = ;
while(i < slen&&j < plen)
{
if(haystack[i] == needle[j])
{
i++;
j++;
}
else
{
if(s + plen < slen)// 要判断 s + plen那个一个元素是否存在
{
char c = haystack[s+plen];
s = s + dis[c - 'a'];
i = s;
j = ;
}
else
{
return NULL;
}
}
} if(j == plen)return haystack+s;
else return NULL;
}
int main()
{
char* str = "ababcdababa";
char* p = "ababa";
char* q = NULL;
q = strStr(str,p); if(q == NULL)puts("NO");
if(q!=NULL)printf("%s\n",q); }

字符串模式匹配sunday算法的更多相关文章

  1. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  2. 字符串模式匹配——KMP算法

    KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...

  3. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. NET免费服务器

    NET免费服务器 1.先注册一个号.地址:https://appharbor.com/ 2.看看有没有你需要的插件,基本上都是免费的 3.本地创建git库 4.复制git远程仓库的地址 5.推送到远程 ...

  2. 写一个EF的CodeFirst的Demo

    写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...

  3. C# - (0x80040154): Retrieving the COM class factory for component with CLSID {877AA945-1CB2-411C-ACD7-C70B1F9E2E32} failed

    1. Exeption Error: System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM clas ...

  4. 2659: [Beijing wc2012]算不出的算式 - BZOJ

    最近有点颓废,刷水题,数学题(根本不会做啊) 题意:求 q,p是两个奇质数 网上题解就直接说是几何意义,问了别人才知道 我们在坐标轴上画出来就是在线段y=(q/p)x下方的格点和y=(p/q)x下方的 ...

  5. 使用了非标准扩展:“xxx”使用 SEH,并且“xxx”有析构函数

    如果一个函数内使用了异常处理机制, VC 编译器在编译该函数时,它会给此函数插入一些“代码和信息”(代码指的是当该函数中出现异常时的回调函数,而信息主要是指与异常出现相关的一些必要的链表),因此每份函 ...

  6. Machine Learning Done Wrong

    Machine Learning Done Wrong Statistical modeling is a lot like engineering. In engineering, there ar ...

  7. 解决jquery版本冲突问题

    解决jQuery1.3.2和1.4.2的冲突.(测试通过) 第一步:在1.4.2的源代码的最后加上一句 var $j4 = jQuery.noConflict(true);//之所以在源码这里加,而不 ...

  8. Synchronized Methods

    Synchronized Methods The Java programming language provides two basic synchronization idioms: synchr ...

  9. ZOJ 2724 Windows Message Queue (优先级队列,水题,自己动手写了个最小堆)

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  10. POJ 1054 The Troublesome Frog(枚举+剪枝)

    题目链接 题意 :给你r*c的一块稻田,每个点都种有水稻,青蛙们晚上会从水稻地里穿过并踩倒,确保青蛙的每次跳跃的长度相同,且路线是直线,给出n个青蛙的脚印点问存在大于等于3的最大青蛙走的连续的脚印个数 ...