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

 

转载于:https://www.cnblogs.com/acSzz/p/5793675.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值