kmp模式匹配

朴素的模式匹配算法,是将子串与主串匹配,如果发生不匹配,则子串下标退回到原点,主串下标加1,从头开始匹配。这样的算法简单易懂,但进行了很多次无用的匹配,时间复杂度为O(m*n)。

而KMP模式匹配在朴素的模式匹配上加以改进,省略掉了很多的重复的比较过程,例如主串为abbabbe,子串为abbe

kmp模式匹配就是这样通过检查子串中的后缀是否与前缀相匹配的方法,确定子串回溯的位置,这样就能省去很多次无用的匹配,优化了算法。

于是问题的关键变成了怎样找到子串应该回溯的位置。子串回溯的位置只有子串的结构有关,子串的每一个位置都有一个回溯值,当子串与主串再此发生不匹配时,子串就回溯到该位置。定义该回溯数组为next【】。

ok,i think you must want to say shut your mouth and show me the code.

//      该方法用来寻找子串的next[]数组
public static int [] getnext(String T)
{
//      j表示子串中的下标
    int j = 1;
//      k表示前缀与子串后缀相匹配的最大值
    int k = 0;
    int [] next = new int[T.length()];
//      初始化next[0]=-1,next[1]=0
    next[0] = -1;
    next[1] = 0;
    while(j<T.length()-1)
    {
//          如果前缀等于后缀,next[j+1]=k+1
        if(T.charAt(j)==T.charAt(k))
        {
            next[j+1] = k+1;
            j++;
            k++;
        }
        else if (k == 0) 
        {
            next[j+1] = 0;
            j++;
        }
//          如果不匹配,k值回溯。相当于子串中进行一次模式匹配
        else
            k = next[k];
    }
//      此处用来验证next[]数组是否正确
//      for (int z = 0; z < next.length; z++) {
//          System.out.print(next[z]);
//      }
    return next;
}

在得到next[]数组后,即可进行kmp模式匹配

//  实现kmp模式匹配
public static int kmp_index(String s,String t) {
    int i = 0;
    int j = 0;
//      获得next[]数组
    int next[] = getnext(t);
    while (i<s.length()&&j<t.length()) {
        if (j == -1||s.charAt(i) == t.charAt(j)) {
            i++;
            j++;
        }
//          如果不匹配,j回溯至当前j值的next[j]处
        else {
            j = next[j];
        }
    }
    if (j == t.length()) {
        return i-t.length();
    }
    else {
        return -1;
    }
}
//  测试kmp模式匹配
//  public static void main (String [] args) {
//      String string1 = "aaabbbaaab";
//      String string2 = "bbbaaa";
//      getnext(string2);
//      int i = kmp_index(string1, string2);
//      System.out.println(i);
//  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值