1. 程式人生 > >java實現Brute-Force和KMP模式匹配

java實現Brute-Force和KMP模式匹配

Brute-Force模式匹配演算法

從主串第start(i=start)個字元起,與模式串t的第一個字元(j=0)開始比較。

若相等,則繼續比較後面字元(i++,j++)

若不相等,則從主串第二個字元起重新和模式串t比較(i=i-j+1,j=0)

若都匹配成功,則返回模式串t第一個字元在主串的位置

否則返回-1

public int index_BF(IString t,int start){  //t為模式串
		int slen=this.length();
		int tlen=t.length();
		int i=start;
		int j=0;
		while(i<slen&&j<tlen){    
			if(this.charAt(i)==t.charAt(j)){   //j為模式串當前字元下標
 				i++;
				j++;
			}
			else{
				i=i-j+1;    //繼續比較後續字元
				j=0;   //模式串下標回退到0
			}
		}
		if(j>=t.length())    //匹配成功,返回子串序號
			return i-tlen;
		else             //匹配失敗,返回-1
			return -1;
		
	}
KMP模式匹配

個人感覺以下這篇文章不錯,舉了一個例子來理解KMP,簡單直觀,不過他是用c寫的

下面我用java實現

點選開啟連結

首先建立next[]函式

//next[0]=-1表示0個元素,不存在前後綴
    //next[1]=0表示有一個元素,前後綴長度為0
    //next[2]=1表示有兩個元素,前後綴長度為1
    public int[] getnext(IString T){
        int[]next=new int[T.length()];  //next陣列
        int j=1;    //主串指標
        int k=0;     //模式串指標
        next[0]=-1;
        next[1]=0;
        while(j<T.length()-1){   
            if(T.charAt(j)==T.charAt(k)){   //匹配
                next[j+1]=k+1;
                k++;
                j++;
            }
            else if(k==0){   //失配
                next[j+1]=0;
                j++;
            }
            else
                k=next[k];
        }
        return(next);
    }
KMP演算法實現

public int index_KMP(IString T,int start){
		int[]next=getnext(T);  //計算模式串的next【】函式值
		int i=start;
		int j=0;
		while(i<this.length()&&j<T.length()){ //從左到右依次比較
			if(j==0||this.charAt(i)==T.charAt(j)){  //j==0表示S[i]!=T[0]則轉到下一字元
				i++;
				j++;
			}
			else   //當S[i]!=T[j]時,模式串右移
				j=next[j];
		}
		if(j<T.length())   //匹配失敗
			return -1;
		else              //匹配成功
			return(i-T.length());   
	}
	public int index_BF(IString t,int start){  //t為模式串
		int slen=this.length();
		int tlen=t.length();
		int i=start;
		int j=0;
		while(i<slen&&j<tlen){    
			if(this.charAt(i)==t.charAt(j)){   //j為模式串當前字元下標
 				i++;
				j++;
			}
			else{
				i=i-j+1;    //繼續比較後續字元
				j=0;   //模式串下標回退到0
			}
		}
		if(j>=t.length())    //匹配成功,返回子串序號
			return i-tlen;
		else             //匹配失敗,返回-1
			return -1;
		
	}