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