int kmp(char * t,int lenT,char * pat,int lenPat){ int posP=0,posT=0; int[] f=partialMatch(pat,lenPat)//獲取pat字符串的部分匹配數組 while(posP<lenPat && posT<lenT){ if(pat[posP]==t[posT]){ posT++; posP++; } else if(posP==0) posT++;//第一就不匹配,目標字符串向後移動 else posP=f[posP-1]+1;//前面都匹配,則將搜索字符串,直接移動到未比較過的位置 } if(posP<lenPat)return -1;//若是posP沒有遍歷完搜索字符串,則說明沒有找到 else return posT-lenPat; //找到了,則返回在目標字符串中的起始位置 } /*遞推方法: f[j]=k,str[0:k-1]== str[j-k:j-1],這是從str[0:j-1]中找到其前綴子串集合和其後綴子串集合的交集中的最大子串。 假設 f[j]=k,即str[0:k-1]==str[j-k:j-1] 若是 str[k]== str[j] => str[0:k]==str[j-k:j] => f[j]=k+1 若是 str[k]!=str[j] => 若是找到最大整數 h,知足str[0:h-1]==str[k-h:k-1],即f[k]=h,也就是說str[0:k-1]中存在一個最大子串str[0:h-1], 而後判斷str[h+1]與str[j]是否相等,若是不等,再從str[0:h-1]子串中去找到最大子串,而後再去判斷 若是找不到 最大子串, 則f[j+1]=-1 */ int[] partialMatch(char * s,int len){ int[] f=new int[len]; f[0]=-1;//遞推種子 for(int j=0;j<len-1;j++){ int k=f[j]; while(k>=0 && *(s+j+1)!=*(s+k+1)) k=f[k]; //判斷是否有子串符合 *(s+j)==*(s+k+1),若是不等,從子串中繼續找最大子串。 if(*(s+j+1)==*(s+k+1)) f[j+1]=k+1; else f[k]=-1; } }
一直都沒看懂,直到看了這篇文章:http://kb.cnblogs.com/page/176818/數組