KMP算法

自己实现了下kmp算法,感觉失败的地方要反复比较,这个比较浪费:

public class KMP {
    public static int[] calcNextArray(char[] target) {
        int[] next = new int[target.length];
        next[1] = 0;
        for (int i = 2; i < target.length; ++i) {
            int j = next[i - 1];
            while (target[j] != target[i - 1] && j != 0) { j = next[j]; }
            next[i] = (target[j] == target[i - 1] ? (j + 1) : 0);
        }
        return next;
    }

    public static int findStr(char[] str, char[] target) {
        int[] next = calcNextArray(target);
        int i = 0, j = 0;
        for (; ;) {
            if (str[i] == target[j]) {
                ++i;
                ++j;
                if (i >= str.length || j >= target.length) {
                    break;
                }
            } else if (j == 0) {
                ++i;
                if (i >= str.length) {
                    break;
                }
            } else {
                j = next[j];
            }
        }
        if (j == target.length) {
            return i - target.length;
        }
        return -1;
    }
}
做了一下简单的单元测试:

public class KMPTest {
    @Test
    public void testNextArray() {
        String target = "abacab";
        int[] next = KMP.calcNextArray(target.toCharArray());
        assertEquals(next[1], 0);
        assertEquals(next[2], 0);
        assertEquals(next[3], 1);
        assertEquals(next[4], 0);
        assertEquals(next[5], 1);

        target = "aaabaaa";
        next = KMP.calcNextArray(target.toCharArray());
        assertEquals(next[1], 0);
        assertEquals(next[2], 1);
        assertEquals(next[3], 2);
        assertEquals(next[4], 0);
        assertEquals(next[5], 1);
        assertEquals(next[6], 2);
    }

    @Test
    public void testKMP() {
        String str = "abacaabacabacabaabb";
        String target = "abacab";
        assertEquals(5, KMP.findStr(str.toCharArray(), target.toCharArray()));
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值