快速字串模糊匹配--基於Horspool的模糊匹配演算法
阿新 • • 發佈:2019-01-28
背景知識
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'];
}
}