文字部分转自: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. JPA学习---第二节:JPA开发环境和思想介绍

    一.下载相关 jar http://hibernate.org/orm/ 下载 hibernate ,解压 http://www.slf4j.org/download.html 下载 slf4j,解压 ...

  2. NodeJS -Express 4.0 用include取代partial

    在Express 4.0 下按如下方法设置: (1)运行cmd 输入:npm install express-partials -g (2)下载成功后.在app.js 中引用此插件   var par ...

  3. 从一个新手容易混淆的例子简单分析C语言中函数调用过程

    某天,王尼玛写了段C程序: #include <stdio.h> void input() { int i; ]; ; i < ; i++) { array[i] = i; } } ...

  4. java笔记之类和对象

    现在编程的思想分成了两大阵营,面向过程和面向对象.现在谈谈啥是面向对象. 作为一只单身狗,谈“对象”还是很伤心很伤心的(:′⌒`)...... 先看看百度怎么说? 好吧,百度说的太抽象,我换个简单的说 ...

  5. angular入门系列教程1

    主题: 一个能够跑起来的页面,神奇的效果,无需一样JS代码! 效果图: 细节: 当然,这里甚至连登陆都没做,只是看到神奇的当输入用户名或者密码的时候,下面的预览区域也会有相应的更改.没有一行的JS代码 ...

  6. ios Camera学习笔记

    检测设备的摄像头是否可用: - (BOOL) isCameraAvailable{ return [UIImagePickerController isSourceTypeAvailable: UII ...

  7. MVC3+AutoFac实现程序集级别的依赖注入

    1.介绍      所谓程序集级别的依赖注入是指接口和实现的依赖不使用配置文件或硬代码实现(builder.RegisterType<UserInfoService>().As<IU ...

  8. PHP中如何给日期加上一个月 加一周 加一天

    echo   date("Y-m-d",strtotime("+1 month",strtotime("2012-02-04"))); 结果 ...

  9. JS常见排序算法

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

  10. 盘点 DevOps 世界的杰出女性(一)

    [编者按]IT 领域从来不缺乏杰出的女性存在,近日,DevOps.com 主编 Alan Shimel 盘点了 DevOps 领域的杰出女性,首期为六个,本文系 OneAPM 工程师编译整理. 以下为 ...