字符串模式匹配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

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string>
 4 #include <string.h>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <map>
 8 #include <stack>
 9 #include <queue>
10 #include <math.h>
11 #define maxn 100100
12 #define N 22000
13 using namespace std;
14 int dis[30];
15 char *strStr(char *haystack, char *needle)
16 {
17        //haystack 表示母串
18        // needle 表示子串
19        int slen = strlen(haystack);
20        int plen = strlen(needle);
21
22        int dis[26];// 表示当不匹配时跳过的距离
23
24        for(int i = 0 ; i < 26;i++)
25        {
26            dis[i] = plen+1;// 初始化为子串长度+1
27
28        }
29
30        for(int i = 0 ; i < plen;i++)
31        {
32            dis[needle[i] - ‘a‘] = plen - i;
33        }
34
35
36        int s = 0;
37        int i = s;
38        int j = 0;
39
40
41        while(i < slen&&j < plen)
42        {
43            if(haystack[i] == needle[j])
44            {
45                i++;
46                j++;
47            }
48            else
49            {
50                if(s + plen < slen)// 要判断 s + plen那个一个元素是否存在
51                {
52                    char c = haystack[s+plen];
53                    s = s + dis[c - ‘a‘];
54                    i = s;
55                    j = 0;
56                }
57                else
58                {
59                    return NULL;
60                }
61            }
62        }
63
64        if(j == plen)return haystack+s;
65        else return NULL;
66
67
68 }
69 int main()
70 {
71     char* str = "a";
72     char* p = "a";
73     char* q = NULL;
74     q = strStr(str,p);
75
76     if(q == NULL)puts("NO");
77     if(q!=NULL)printf("%s\n",q);
78
79 }
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string>
 4 #include <string.h>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <map>
 8 #include <stack>
 9 #include <queue>
10 #include <math.h>
11 #define maxn 100100
12 #define N 22000
13 using namespace std;
14 int dis[30];
15 //返回出现的第一个位置,否则返回NULL
16 char *sunday(char *haystack, char *needle)
17 {
18        //haystack 表示母串
19        // needle 表示子串
20        int slen = strlen(haystack);
21        int plen = strlen(needle);
22
23        int dis[26];// 表示当不匹配时跳过的距离
24
25        for(int i = 0 ; i < 26;i++)
26        {
27            dis[i] = plen+1;// 初始化为子串长度+1
28
29        }
31        for(int i = 0 ; i < plen;i++)
32        {
33            dis[needle[i] - ‘a‘] = plen - i;
34        }
35
37        int s = 0;
38        int i = s;
39        int j = 0;
42        while(i < slen&&j < plen)
43        {
44            if(haystack[i] == needle[j])
45            {
46                i++;
47                j++;
48            }
49            else
50            {
51                if(s + plen < slen)// 要判断 s + plen那个一个元素是否存在
52                {
53                    char c = haystack[s+plen];
54                    s = s + dis[c - ‘a‘];
55                    i = s;
56                    j = 0;
57                }
58                else
59                {
60                    return NULL;
61                }
62            }
63        }
64
65        if(j == plen)return haystack+s;
66        else return NULL;
69 }
70 int main()
71 {
72     char* str = "ababcdababa";
73     char* p = "ababa";
74     char* q = NULL;
75     q = strStr(str,p);
76
77     if(q == NULL)puts("NO");
78     if(q!=NULL)printf("%s\n",q);
79
80 }
时间: 2024-10-13 00:43:42

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

字符串模式匹配KMP算法中的next数组算法及C++实现

一.问题描述: 对于两个字符串S.T,找到T在S中第一次出现的起始位置,若T未在S中出现,则返回-1. 二.输入描述: 两个字符串S.T. 三.输出描述: 字符串T在S中第一次出现的起始位置,若未出现,则返回-1. 四.输入例子: ababaababcbababc 五.输出例子: 5 六.KMP算法解析: KMP算法分为两步,第一步是计算next数组,第二步是根据next数组通过较节省的方式回溯来比较两个字符串. 网络上不同文章关于next数组的角标含义略有差别,这里取参考文献中王红梅<数据结构

字符串模式匹配的几种算法

1.KMP算法 KMP算法程序看起来比较简单,但是求next数组的过程还是比较难理解,next数组实质就是求最大的前后缀,该算法的复杂度是O(m+n),算法流程如下: 假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置 如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符: 如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j].此举意味着失配时,模式串P相对于文本串S向右移动了

字符串匹配算法之sunday算法

本节介绍一下sunday算法,看一下sunday算法是如何做的呢 首先定义连个字符串 src:abcdacdaahfacabcdabcdeaa pattern:abcde 我们的目的就是在src串中查找pattern串是否存在,找的方法如下 1. 先左对齐,即从src[0].pattern[0]开始,进行依次比较,比较结果如下 arc[0]=pattern[0] 比较成功 arc[1]=pattern[1] 比较成功 arc[2]=pattern[2] 比较成功 arc[3]=pattern[3

【算法视频】字符串模式匹配--布鲁特.福斯算法

2.4.字符串模式匹配 资讯网址:www.qghkt.com 腾讯课堂:https://qghkt.ke.qq.com/20个常用算法 模式串(或子串)在主串中的定位操作通常称为串的模式匹配,它是各种串处理系统中最重要的运算之一. 2.4.1.布鲁特-福斯算法 [基本思想] 从主串的第一个字符起与模式串的第一个字符比较,若相等,则继续逐个字符进行后续比较,否则从主串的第二个字符起与模式串的第一个字符重新开始比较,直至模式串中每个字符依次与主串中的一个连续的字符序列相等时为止,此时称为匹配成功:如

字符串匹配的sunday算法

sunday算法核心思想:启发式移动搜索步长! SUNDAY 算法描述: 字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).这里介绍一种比BM算法更快一些的sunday查找算法. 例如我们要在"substring searching algorithm"查找"search",刚开始时,把子串与文本左边对齐: substring searching algorithm search ^ 结果在第二个

字符串匹配-sunday算法

#include<iostream> using namespace std; //匹配字符串.能匹配子串在原始字符串中所有出现的位置的开始下标,下标以0开始. int match(int i, int n, const char *ori, const char *sub) {  int j;  for (j = 0; j < n; j++)  {   if (ori[i] == sub[j])   {    if (j == n - 1)    {     cout <<

13.字符串-模式匹配

一般提起字符串的相关算法,就是几个基本的算法:赋值strcpy.求长strlen.联接strcat.比较strcmp和求子串substr.这5个操作相对来说都比较简单,构成了字符串的最小操作集,其他的算法都可以由这几个算法来实现.但是实际应用中,模式匹配index是应用非常广泛的字符串操作,我们倾向于不依赖其他的操作来实现它. 一般匹配 如下图,在目标字符串S中查找模式字符串T的最直白的做法就是: 1.分别用i.j指向字符串 2.依次遍历,S[i]==T[j]则i++.j++ 3.S[i]!=T

字符串匹配算法KMP算法

数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法. 朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多多余的不符合的匹配做了冗余的比较.假设源字符串长n,字串长m 该算法最差时间复杂度为 m*(n-m+1),记为O(n*m);这里不做过多解释朴素匹配算法. KMP算法: kmp算法不是在源字符串中下手,他是从字串下手,比如我要在源字符串(acabaabaabcacaabc)中匹配一个字符串字串(ab

Sunday算法模板

Sunday是一个线性字符串模式匹配算法.算法的概念如下: Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法.其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率. 记模式串为S,子串为T,长度分别为N,M. 对于T,我们做一个简单而巧妙的预处理:记录T中每一种字符最后出现的位置,将其存入一个数组中. 假设在发生不匹配时S[i]≠T[j],