字符串匹配算法--sunday算法

作者:houskii
链接:https://www.jianshu.com/p/2e6eb7386cd3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

算法解释

根据上述作者整理得到,有自己的理解

Sunday算法和BM算法稍有不同的是,Sunday算法是从前往后匹配,在匹配失败时关注的是主串中参加匹配的最末位字符的下一位字符。

  • 如果该字符没有在模式串中出现则直接跳过,即移动位数 = 模式串长度 + 1;
  • 否则,其移动位数 = 模式串长度 - 该字符最右出现的位置(以0开始) = 模式串中该字符最右出现的位置到尾部的距离 + 1。

下面举个例子说明下Sunday算法。假定现在要在主串”substring searching”中查找模式串”search”。

  • 刚开始时,把模式串与文主串左边对齐:

     
    Sunday算法1
  • 结果发现在第2个字符处发现不匹配,不匹配时关注主串中参加匹配的最末位字符的下一位字符,即标粗的字符 i,因为模式串search中并不存在i,所以模式串直接跳过一大片,向右移动位数 = 匹配串长度 + 1 = 6 + 1 = 7,从 i 之后的那个字符(即字符n)开始下一步的匹配,如下图:
     
    Sunday2
  • 结果第一个字符就不匹配,再看主串中参加匹配的最末位字符的下一位字符,是’r’,它出现在模式串中的倒数第3位,于是把模式串向右移动3位(m - 3 = 6 - 3 = r 到模式串末尾的距离 + 1 = 2 + 1 =3),使两个’r’对齐,如下:


     
    Sunday3
  • 匹配成功。

 

 1 static final int ASCII_SIZE = 126;   
 2 
 3 int sunday(char[] total,char[] part){
 4         int tSize = total.length;
 5         int pSize = part.length;
 6         int[] move = new int[ASCII_SIZE];//这个move[i],i代表的是某个字符对应的int数!!!!!很关键
 7         //主串参与匹配最末位字符移动到该位需要移动的位数
 8         for (int i= 0;i<ASCII_SIZE;i++){
 9             move[i] = pSize+1;
10         }
11        
12         for (int i = 0;i<pSize;i++){
13             move[part[i]] = pSize-i;
14         }
15         
16         int s = 0;//模式串头部在字符串位置
17         
18         int j;//模式串已经匹配了的长度
19         
20         while(s<=tSize-pSize){//到达末尾之前
21             j = 0;
22             while(total[s+j]==part[j]){
23                 j++;
24                 if (j>=pSize){
25                     return s;
26                 }
27             }
28             s+=move[total[s+pSize]];
29         }
30         return -1;
31     }

 



posted @ 2019-05-20 15:16  pc_m  阅读(337)  评论(0)    收藏  举报