1. 程式人生 > >快速字串模糊匹配--基於Horspool的模糊匹配演算法

快速字串模糊匹配--基於Horspool的模糊匹配演算法

背景知識

這裡寫圖片描述

BPM演算法(適用於m<w的模式串)

1.預處理。

這裡寫圖片描述

1)初始化位向量,每個位都置為0;

public void initVector(){
        size = CHAR_SIZE*p.length();
        bitArray = new int[(size-1)/BIT_LENGTH+1];
        //將位向量全部清零
        for(int i=0;i<n;++i){
            P = i/BIT_LENGTH;   
            Q = i%BIT_LENGTH;
            bitArray[P] |= 1
<<(31-Q); } }

2)對字符集的每一個字元計算其二進位制模式表示

    /********************/
for(int i=0;i<26;++i){
            for(int j=0;j<p.length();++j){
                if(p.toLowerCase().charAt(j)-'a'==i){
                    //將第index位置為1
                    System.out.println("i="+i+"j="+j);
                    int
index = i*p.length()+j; set(index); } } } /********************/ public void set(int i){ P = i/BIT_LENGTH; Q = i%BIT_LENGTH; bitArray[P] |= 1<<(BIT_LENGTH-Q-1); }
在匹配演算法實現中,chk陣列將取代pat.  儲存chk陣列共需要 m*|∑|個二進位制位空間大小,但是實際上除了在pat中出現的字元,別的對應的值為全零,這個演算法需O(m+|∑|)的時間花費。

2.結合Horspool演算法和chk陣列實現模糊匹配。初始化跳轉陣列。
這裡寫圖片描述

//初始化跳轉陣列

        int[] bmbc = new int[CHAR_SIZE];
        for(int i=0;i<CHAR_SIZE;++i){
            bmbc[i] = p.length();
            boolean flag = false;
            for(int j=0;j<4;++j){
                if(get(i*4+j)==1){
                    System.out.println("true");                 
                    flag=true;
                    break;
                }
            }
            //i代表的字元出現在模式串中
            if(flag==true){
                for(int j=0;j<p.length()-1;++j){
                    int index = i*4+j;
                    P = index/BIT_LENGTH;
                    Q = index%BIT_LENGTH;
                    //i所對應的字元出現在模式串的第j位
                    if(get((bitArray[P]&(1<<(BIT_LENGTH-1-Q))),Q)==1){
                        bmbc[i]=p.length()-j-1;
                    }
                }
            }
        }
        return bmbc;
    }

3.匹配檢索部分。發現文字串中所有匹配模式串的部分。

public void bpm(){
        int[] bmbc = PreBmbc();         
        int j = 0;
        int m = p.length();
        int n = t.length();
        while(j<=n-m){
            char ch = t.charAt(j+m-1);
            //從右向左比較,相等則迴圈其中的為二進位制與運算。
            //判斷  text[j+i]是否等於pi 
            int i = 0;
            for(i = m-1;i>=0;--i){

                int index =charToInt(t.charAt(j+i))*4;          
                System.out.println(t.charAt(j+i)+":"+index/4);
                int P1 = index / BIT_LENGTH;
                int Q1 = index % BIT_LENGTH;
                int temp=bitArray[P1]&(1<<(BIT_LENGTH-Q1-i-1));
                int result=get(temp,Q1+i);
                if(result!=1)       
                {
                    break;
                }

            }               
                //發現匹配,報告位置
                if(i<0){
                    System.out.println("匹配位置為:"+j);
                }
                //設定右移引數,繼續檢索下一匹配
                j+=bmbc[ch-'a'];
        }
    }