1. 程式人生 > >Brute-Force 演算法與KMP演算法

Brute-Force 演算法與KMP演算法

串的模式匹配

串的模式匹配也叫查詢定位,指的是在當前串中尋找模式串的過程。主要的模式匹配演算法有 Brute-Force 演算法 和 KMP 演算法;

Brute-Force 演算法

Brute-Force 演算法從主串的第一個字元開始和模式串的第一個字元進行比較,若相等,則繼續比較後續字元;否則從主串的第二個字元開始重新和模式串進行比較。依次類推,直到模式串的每個字元依次與主串的字元相等,匹配成功;
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

    //從位序號為begin的字元開始搜尋與str相等的子串
	public int BF(String str, int begin) throws Exception {
if(str.length()<=curLen&&str!=null&&curLen>0){ int i=begin; int len=str.length(); while(i<=curLen-len){//從主串的第i個元素開始比較 for(int j=0;j<len;j++){//比較模式串的元素 if(str.charAt(j)!=strValue[j+i]){ i++; break; //跳出當前迴圈 } else if(j==len-1){
//len個字元全部匹配成功 return i; } } } } return -1; }

Brute-Force 演算法的實現簡單,但效率非常低。
測試:

public class A {
	private char[] strValue;//字元陣列存放串值
	private int curLen;//當前串的長度
	
	//構造空串
	public A(){
		strValue=new char[0];
		curLen=0;
	}
	//以字串常量構造串
	public A(String str){
		char[] p=str.
toCharArray(); strValue=p; curLen=p.length; } //從位序號為begin的字元開始搜尋與str相等的子串 public int BF(String str, int begin) throws Exception { if(str.length()<=curLen&&str!=null&&curLen>0){ int i=begin; int len=str.length(); while(i<=curLen-len){//從主串的第i個元素開始比較 for(int j=0;j<len;j++){//比較模式串的元素 if(str.charAt(j)!=strValue[j+i]){ i++; break; //跳出當前迴圈 } else if(j==len-1){//len個字元全部匹配成功 return i; } } } } return -1; } public static void main(String[] args) throws Exception{ A aa =new A("ssdfgasdbababa"); int result = aa.BF("fg", 0); System.out.println(result); //輸出3 } }

KMP 演算法

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

因此我們需要:

  1. 取得目標字串的匹配值陣列next[];
  2. 根據next[]陣列實現KMP演算法;

求陣列next[]:

public static int[] kmpnext(String dest){
        int[] next = new int[dest.length()];
        next[0] = 0;
        for(int i = 1,j = 0; i < dest.length(); i++){
            while(j > 0 && dest.charAt(j) != dest.charAt(i)){
                j = next[j - 1];
            }
            if(dest.charAt(i) == dest.charAt(j)){            	
                j++;
            }
            next[i] = j;
        }
        return next;
    }

KMP實現:

    public static int kmp(String str, String dest,int[] next){//str文字串  dest 模式串
        for(int i = 0, j = 0; i < str.length(); i++){
            while(j > 0 && str.charAt(i) != dest.charAt(j)){
                j = next[j - 1];
            }
            if(str.charAt(i) == dest.charAt(j)){
                j++;
            }
            if(j == dest.length()){
                return i-j+1;
            }
        }
        return 0;
    }

測試:

    public static void main(String[] args){
    	//String a = "ababa";       輸出9 0 0 1 2 3
       // String b = "ssdfgasdbababa";
    	String a = "dfg";        //輸出2 0 0 0
        String b = "ssdfgasdbababa";    
        int[] next = kmpnext(a);
        int res = kmp(b, a,next);
        System.out.println(res);
        for(int i = 0; i < next.length; i++){
            System.out.println(next[i]);            
        }
        
    }

以上的內容來自51CTO學院的資料結構課程,我只是整理了一下以便日後方便複習,如有侵權我會自行刪除;
原文:http://edu.51cto.com/center/course/lesson/index?id=68078
挺好理解的,講師講的很通熟易懂,想學習的可以去看原版視訊;