日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构java语言kmp_数据结构(java语言描述)模式匹配——KMP算法

發(fā)布時(shí)間:2023/12/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构java语言kmp_数据结构(java语言描述)模式匹配——KMP算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)于模式匹配算法,BF是比較號(hào)理解的,但是屬于暴力匹配,資源浪費(fèi)太嚴(yán)重。

KMP算法確實(shí)比較難懂(PS:反正我是看了好久才弄明白,可能也是我理解能力太差=_=)

下面是我的一些心得。

http://www.cnblogs.com/yjiyjige/p/3263858.html

這個(gè)是我在網(wǎng)上找到的一個(gè)網(wǎng)友的帖子,覺得將得很詳細(xì),看了之后恍然大悟。

1.原理

KMP算法原理就是在主串和子串做匹配的時(shí)候,每次遇到不想同的元素即不能繼續(xù)匹配時(shí),保持主串正在匹配的那個(gè)元素不變,至變更子串的元素(向前移動(dòng)游標(biāo)),從而達(dá)到減小時(shí)間復(fù)雜度的目的。即:“利用已經(jīng)部分匹配這個(gè)有效信息,保持i指針不回溯,通過修改j指針,讓模式串盡量地移動(dòng)到有效的位置。”

結(jié)合這個(gè)帖子:http://www.cnblogs.com/tangzhengyue/p/4315393.html

我覺得最重要的是這個(gè)圖要懂:

代碼中,BMP方法部分相比于BF算法改動(dòng)不大,主要是在判斷條件上加了一個(gè)

當(dāng)si=tj時(shí),i/j分別加1,繼續(xù)比較;

當(dāng)si!=tj時(shí),i值不變,j變?yōu)閚ext(j),繼續(xù)比較。

做比較時(shí)有:1.j退回到next[j]時(shí),若si=tj(tnext(j)),則i/j分別加1,繼續(xù)比較,若si!=tj(tnext(j)),則j退回j=next[next[j]](即退回k=next[j],j=next[k],這是一個(gè)遞歸,直到k=-1,此時(shí)next[k]=0,k=1,next[k]=0);

2.j退回到j(luò)=-1時(shí),另主串和子串下標(biāo)各加1.

分析條件,子串中的元素要進(jìn)行比較的情況有:如上黃顏色標(biāo)出的情況,進(jìn)行綜合得:

有代碼:

int j=-1;

while(i

if(j==-1||p[i]==s[i]){

i++;j++}

else{

j=next[j];}}

關(guān)于j的變化關(guān)系由一個(gè)next數(shù)組來存儲(chǔ)。

對(duì)整個(gè)子串進(jìn)行遍歷:(0<=j

int[] next1=new int[s.length];//next數(shù)組初始化

next1[0]=-1;//next數(shù)組的第一個(gè)元素初始化

int j=0;

int k=-1;//初始化

while(j

{

if(k==-1||s[j]==s[k])//如果s[j]==s[k]或k==-1,則需要移動(dòng)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)

//此時(shí)s[j]!=s[k]

k=next1[k];//取k結(jié)束的串的最長匹配子串

}

總代碼:

package exercise;

import java.util.Scanner;

public class KMP {//與BF算法有四個(gè)不同的地方

public static int km(String s1,String s2){

char[] p=s1.toCharArray();

char[] s=s2.toCharArray();

int[] next=getnext(s2);//與BF算法相比多了一個(gè)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是當(dāng)主串和子串的第一個(gè)元素不等時(shí)  多了一個(gè)j的判斷條件 2

i++;

j++;

}else{

//與BF算法不同的是,此時(shí)i不在返回,只有j動(dòng)   //i不動(dòng)????? 3

j=next[j];//j回到指定位置

//j不是移動(dòng)到0,而智能的移動(dòng)到字串中的最長匹配串的結(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();//將要個(gè)生成next數(shù)組的子串轉(zhuǎn)換為char數(shù)組

int[] next1=new int[s.length];//next數(shù)組初始化

next1[0]=-1;//next數(shù)組的第一個(gè)元素初始化

int j=0;

int k=-1;//初始化

while(j

{

if(k==-1||s[j]==s[k])//如果s[j]==s[k]或k==-1,則需要移動(dòng)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)

//此時(shí)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("請(qǐng)輸入主串:");

String p=sc.nextLine();

System.out.println("請(qǐng)輸入子串:");

String s=sc.nextLine();

int i=km(p,s);//靜態(tài)的方法main()只能調(diào)用靜態(tài)的方法b(),因?yàn)殪o態(tài)方法早于對(duì)象而創(chuàng)建,

//調(diào)用非靜態(tài)方法時(shí)要提前創(chuàng)建對(duì)象,非靜態(tài)方法要等對(duì)象創(chuàng)建之后才能被創(chuàng)建

System.out.println("子串在主串中的位置:"+i);

}

}結(jié)果:

請(qǐng)輸入主串:

ababcabdabcabca

請(qǐng)輸入子串:

abcabc

j:1

k:0

j:2

k:0

-1 0 0 -1 0 0 子串在主串中的位置:8

總結(jié)

以上是生活随笔為你收集整理的数据结构java语言kmp_数据结构(java语言描述)模式匹配——KMP算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。