字符串匹配 KMP算法

介绍

用传统的暴力匹配的方法进行字符串匹配的时间复杂度太大,效率往往不高。KMP算法减少了很多不必要的比较操作,通过已经匹配主串的前缀中的最长可匹配后缀和模式串中的最长可匹配前缀使得模式串的快速移动。时间复杂度可达O(n + m) 【n,m分别是主串和模式串的长度】

next数组

算法的关键是找到主串最长可匹配后缀和模式串中的最长可匹配前缀,由于前面的部分是已经匹配的,我们可以直接在模式串中生成next数组。下标指的是j位置不匹配,j位置前的子串都匹配。next存的是最长可匹配前缀串的长度,也即最长可匹配前缀的下一个位置。比如ABAB就是2, ABABA就是3。
在找到nxt数组之后,每次如果在模式串的j位置匹配失败,我们只需要让j = next[j],这样在模式串之前的部分是可以和主串匹配的最长前缀,然后继续重复这个过程,直到匹配成功或失败

代码

   public class KMP {

    public static void main(String[] args) {
        String str1 = "ATCGAGAGAAGCTTGCATGCAGTGCA";
        String str2 = "GAGAAGCT";
        System.out.println(kmp(str1, str2));
    }

    static int kmp(String str, String pattern){
        int[] nxt = getNext(pattern);
        //i和j分别是主串和模式串的下标
        int j = 0;
        for (int i = 0; i < str.length(); i++) {
            while (j > 0 && str.charAt(i) != pattern.charAt(j)){
                j = nxt[j];
            }
            if (str.charAt(i) == pattern.charAt(j)){
                ++j;
            }
            if (j == pattern.length()){
                return i - pattern.length() + 1;
            }
        }
        return -1;
    }

        static int[] getNext(String pattern){
        int [] nxt = new int[pattern.length()];
        int tail = 2, head = 0;
            for (; tail< pattern.length(); tail++) {
                while (head != 0 && pattern.charAt(head) != pattern.charAt(tail - 1)){
                    head = nxt[head];
                }
                if (pattern.charAt(head) == pattern.charAt(tail - 1)){
                    ++head;
                }
                nxt[tail] = head;
            }
        return nxt;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值