文字部分转自: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. 什么是Hadoop,怎样学习Hadoop

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS.HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上:而且它 ...

  2. mysql安装篇

    装了vps,环境又要自己配置.mysql比较难装上. 1.安装MySQL 5.5.x的yum源:rpm -Uvh http://repo.webtatic.com/yum/centos/5/lates ...

  3. python学习之“切片操作从入门到精通”

    在python学习开发的过程中,我们总是不断的要对List(列表),Tuple(元组)有取值操作:假如我们有一个列表List1现在想取出1其中的前5个元素,改怎么操作呢? >>> L ...

  4. [转载]淘宝API调用 申请 获取session key

    http://www.cnblogs.com/zknu/archive/2013/06/14/3135527.html 在调用淘宝的API时,我们都会用到appkey,appsecret,appses ...

  5. [设计模式] 1/2 工程与抽象工程模式 factory & Abstrac Factory

    转载 http://blog.csdn.net/wuzhekai1985 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多 ...

  6. RFID开发笔记 Alien阅读器文档

    1. 开机使用serial connect,完成boot后使用TCP/IP协议与主机通信 2.TagList,是一个活跃标签的列表,这里活跃的含义是在一个间隔里被监听到.如果一个标签之前没有被监听到, ...

  7. selenium实战脚本集——新浪微博发送QQ每日焦点(火狐)

    selenium实战脚本集(1)——新浪微博发送QQ每日焦点,乙醇用谷歌实现的,下边是用火狐实现的. 代码如下: # coding = utf-8 from selenium import webdr ...

  8. HDU4612 Warm up 边双连通分量&&桥&&树直径

    题目的意思很简单,给你一个已经连通的无向图,我们知道,图上不同的边连通分量之间有一定数量的桥,题目要求的就是要你再在这个图上加一条边,使得图的桥数目减到最少. 首先要做的就是找出桥,以及每个点所各自代 ...

  9. LightOj 1096 - nth Term (矩阵快速幂,简单)

    题目 这道题是很简单的矩阵快速幂,可惜,在队内比赛时我不知什么时候抽风把模版中二分时判断的 ==1改成了==0 ,明明觉得自己想得没错,却一直过不了案例,唉,苦逼的比赛状态真让人抓狂!!! #incl ...

  10. C# 面向对象之概念理解(2)

    委托 如果对象A为了满足某个请求,而寻求另一个对象B的帮助,这被称作是A对B的委托. 对象间的委托,和现实世界中人与人之间的委托一样:如果你“那位”要求你在他外出公干期间帮忙助剪草坪,而你转而雇佣邻居 ...