数据结构java语言kmp_数据结构(java语言描述)模式匹配——KMP算法
關于模式匹配算法,BF是比較號理解的,但是屬于暴力匹配,資源浪費太嚴重。
KMP算法確實比較難懂(PS:反正我是看了好久才弄明白,可能也是我理解能力太差=_=)
下面是我的一些心得。
http://www.cnblogs.com/yjiyjige/p/3263858.html
這個是我在網(wǎng)上找到的一個網(wǎng)友的帖子,覺得將得很詳細,看了之后恍然大悟。
1.原理
KMP算法原理就是在主串和子串做匹配的時候,每次遇到不想同的元素即不能繼續(xù)匹配時,保持主串正在匹配的那個元素不變,至變更子串的元素(向前移動游標),從而達到減小時間復雜度的目的。即:“利用已經(jīng)部分匹配這個有效信息,保持i指針不回溯,通過修改j指針,讓模式串盡量地移動到有效的位置。”
結(jié)合這個帖子:http://www.cnblogs.com/tangzhengyue/p/4315393.html
我覺得最重要的是這個圖要懂:
代碼中,BMP方法部分相比于BF算法改動不大,主要是在判斷條件上加了一個
當si=tj時,i/j分別加1,繼續(xù)比較;
當si!=tj時,i值不變,j變?yōu)閚ext(j),繼續(xù)比較。
做比較時有:1.j退回到next[j]時,若si=tj(tnext(j)),則i/j分別加1,繼續(xù)比較,若si!=tj(tnext(j)),則j退回j=next[next[j]](即退回k=next[j],j=next[k],這是一個遞歸,直到k=-1,此時next[k]=0,k=1,next[k]=0);
2.j退回到j=-1時,另主串和子串下標各加1.
分析條件,子串中的元素要進行比較的情況有:如上黃顏色標出的情況,進行綜合得:
有代碼:
int j=-1;
while(i
if(j==-1||p[i]==s[i]){
i++;j++}
else{
j=next[j];}}
關于j的變化關系由一個next數(shù)組來存儲。
對整個子串進行遍歷:(0<=j
int[] next1=new int[s.length];//next數(shù)組初始化
next1[0]=-1;//next數(shù)組的第一個元素初始化
int j=0;
int k=-1;//初始化
while(j
{
if(k==-1||s[j]==s[k])//如果s[j]==s[k]或k==-1,則需要移動j,或則做單純的做i++ j++,然后值j為0,子串從頭開始
{
if(s[++j]==s[++k]){
next1[j]=next1[k];
}else{
System.out.println("j:"+j);
System.out.println("k:"+k);
next1[j]=k;
}
}else{//s[j]==s[k]和k==-1,都不滿足,則往更深以層次比較next(k)
//此時s[j]!=s[k]
k=next1[k];//取k結(jié)束的串的最長匹配子串
}
總代碼:
package exercise;
import java.util.Scanner;
public class KMP {//與BF算法有四個不同的地方
public static int km(String s1,String s2){
char[] p=s1.toCharArray();
char[] s=s2.toCharArray();
int[] next=getnext(s2);//與BF算法相比多了一個next[]數(shù)組 1
for(int l=0;l
System.out.print(next[l]+" ");
}
int i=0;//主串
int j=0;//子串
while(i
if(j==-1||p[i]==s[j]){//j==-1是當主串和子串的第一個元素不等時 多了一個j的判斷條件 2
i++;
j++;
}else{
//與BF算法不同的是,此時i不在返回,只有j動 //i不動????? 3
j=next[j];//j回到指定位置
//j不是移動到0,而智能的移動到字串中的最長匹配串的結(jié)束位置+1???? 4
}
}//while結(jié)束
if(j==s.length){//s.length
return i-j;
}else{
return -1;
}
}
public static int[] getnext(String s2){
char[] s=s2.toCharArray();//將要個生成next數(shù)組的子串轉(zhuǎn)換為char數(shù)組
int[] next1=new int[s.length];//next數(shù)組初始化
next1[0]=-1;//next數(shù)組的第一個元素初始化
int j=0;
int k=-1;//初始化
while(j
{
if(k==-1||s[j]==s[k])//如果s[j]==s[k]或k==-1,則需要移動j,或則做單純的做i++ j++,然后值j為0,子串從頭開始
{
if(s[++j]==s[++k]){
next1[j]=next1[k];
}else{
System.out.println("j:"+j);
System.out.println("k:"+k);
next1[j]=k;
}
}else{//s[j]==s[k]和k==-1,都不滿足,則往更深以層次比較next(k)
//此時s[j]!=s[k]
k=next1[k];//取k結(jié)束的串的最長匹配子串
}
}
return next1;
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("請輸入主串:");
String p=sc.nextLine();
System.out.println("請輸入子串:");
String s=sc.nextLine();
int i=km(p,s);//靜態(tài)的方法main()只能調(diào)用靜態(tài)的方法b(),因為靜態(tài)方法早于對象而創(chuàng)建,
//調(diào)用非靜態(tài)方法時要提前創(chuàng)建對象,非靜態(tài)方法要等對象創(chuàng)建之后才能被創(chuàng)建
System.out.println("子串在主串中的位置:"+i);
}
}結(jié)果:
請輸入主串:
ababcabdabcabca
請輸入子串:
abcabc
j:1
k:0
j:2
k:0
-1 0 0 -1 0 0 子串在主串中的位置:8
總結(jié)
以上是生活随笔為你收集整理的数据结构java语言kmp_数据结构(java语言描述)模式匹配——KMP算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 18岁初中毕业学Java_刚满十八 初中
- 下一篇: java数据跑不出来,6000条数据,j