快速字符串模糊匹配--基于Horspool的模糊匹配算法

来源:互联网 发布:大数据的实践包括哪些 编辑:程序博客网 时间:2024/05/17 09:12

背景知识

这里写图片描述

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'];        }    }