字符串模式匹配sunday算法
文字部分转自: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算法的更多相关文章
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
- 字符串模式匹配——KMP算法
KMP算法匹配字符串 朴素匹配算法 字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- Sunday算法:字符串匹配算法进阶
背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...
- 字符串匹配算法:Sunday算法
背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...
- Sunday算法(字符串查找、匹配)
字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简单的 ...
- 字符串匹配算法之Sunday算法
字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...
- 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...
- 字符串匹配算法之Sunday算法(转)
字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...
随机推荐
- 分布式文件系统 - FastDFS
分布式文件系统 - FastDFS 别问我在哪里 也许我早已不是我自己,别问我在哪里,我一直在这里. 突然不知道说些什么了... 初识 FastDFS 记得那是我刚毕业后进入的第一家公司,一个技术小白 ...
- python学习笔记30(全局变量的两种解决办法)
先看程序: >>> count = 0 >>> def fuc(count): print count count +=1 >>> for i i ...
- Asp.net弹出层并且有遮罩层
长久以来,asp.net弹出层并且有遮罩层问题都是一个难以解决的问题,鉴于此,我决定写个弹出层发布出来,供大家使用... 这里的doing层是遮罩层,divLogin层是登陆层 若有其他问题请留言或邮 ...
- 1502: [NOI2005]月下柠檬树 - BZOJ
Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的 ...
- 同一机器 部署 两个 jboss
当jboss和oracle在同一机器上时,通常oracle占用8080端口,这时只需要去修改\deploy\jbossweb-tomcat50.sar\server.xml中.当在同一台机器上运行两个 ...
- 140227项目开发及上线过程遇到的10个问题(重点: FCK过滤替换)
1.替换条件判断问题 String s = (String)map2.get("contentIntro"); if(s != null && s.length() ...
- 三层架构和MVC
注:本文章内所有内容都来自互联网,本人主要是起了一个收集的作用 http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三 ...
- C# 面向对象之概念理解(2)
委托 如果对象A为了满足某个请求,而寻求另一个对象B的帮助,这被称作是A对B的委托. 对象间的委托,和现实世界中人与人之间的委托一样:如果你“那位”要求你在他外出公干期间帮忙助剪草坪,而你转而雇佣邻居 ...
- [转]ASP.NET Session 详解
来源:http://www.webshu.net/jiaocheng/programme/ASPNET/200606/1381.html 阅读本文章之前的准备 阅读本文章前,需要读者对以下知识有所了解 ...
- POJ 3318 Matrix Multiplication(矩阵乘法)
题目链接 题意 : 给你三个n维矩阵,让你判断A*B是否等于C. 思路 :优化将二维转化成一维的.随机生成一个一维向量d,使得A*(B*d)=C*d,多次生成多次测试即可使错误概率大大减小. #inc ...