zoukankan      html  css  js  c++  java
  • 字符串模式匹配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
    ",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
    ",q);
    79 
    80 }
  • 相关阅读:
    140704
    140703
    140702
    堆排序
    并查集
    140701
    这年暑假集训-140630
    vim for python
    hihocode 第九十二周 数论一·Miller-Rabin质数测试
    hdu 3157 Crazy Circuits 有源汇和下界的最小费用流
  • 原文地址:https://www.cnblogs.com/acSzz/p/5793675.html
Copyright © 2011-2022 走看看