String匹配字符串,KMP太难理解了,写了一个只匹配首字符的

暴力匹配

最经典的方法,其实效率也没那么差,时间复杂度O(n + k),此处我列举极端情况,就是每次匹配都匹配到最后一位,代码如下:

public class ViolenceMatch {
    public int violenceMatch(String str1, String str2) {
        char[] c1 = str1.toCharArray();
        char[] c2 = str2.toCharArray();
        int i = 0;
        int j = 0;
        while (i < c1.length && j < c2.length)
            if (c1[i] == c2[j]){//匹配字符,当完全匹配str2的时候,此时由于j = c2.length,while就会退出
                i++;
                j++;
            }else {
                i = i - j + 1;
                j = 0;
            }
        if (j == c2.length)
            return i - j;
        else return -1;
    }
}

KMP匹配字符串

原理我都写在注释上了,代码如下:

    public static int kmpSearch(String str1, String str2, int[] next) {
        for (int i = 0, j = 0; i < str1.length(); i++) {
            while (j > 0 && str1.charAt(i) != str2.charAt(j)) j = next[j - 1];
            if (str1.charAt(i) == str2.charAt(j)) j++;
            if (j == str2.length()) return i - j + 1;
        }
        return -1;
    }

    public static int[] kmpNext(String dest) {//得到的是一个数组,保存部分匹配值
        int[] next = new int[dest.length()];//创建该数组
        next[0] = 0;//无论哪一个字符串,其第一个字符的部分匹配值都是0
        for (int i = 1, j = 0; i < dest.length(); i++) {//由于第一个字符的部分匹配值是0,因此可以从第二个字符开始遍历;j是作为第一个字符的指针
            while (j > 0 && dest.charAt(i) != dest.charAt(j))
                j = next[j - 1];//当遇到不匹配的,先控制不越界,由于此时charAt[j]已经比较过了,即与charAt[i]比较过了,可以向前进一位,即优化了,不优化的话写成j = 0;也是可以的
            if (dest.charAt(i) == dest.charAt(j)) j++;//当遇到匹配的字符时,指向第一个字符的指针向后移一位,即j++;
            next[i] = j;//并令在遍历dest的指针等于j
        }
        return next;
    }

匹配首字符匹配法

主要容易理解,而且容易写,代码如下:

    public static int violenceMatch(String dest, String target) {
        char[] destArr = dest.toCharArray();
        char[] targetArr = target.toCharArray();
        int targetLen = targetArr.length;
        int i = 0, j = 0;
        while (i < destArr.length && j < targetLen)
            if (destArr[i] == targetArr[j]) {
                i++;
                j++;
            } else {
                i = getSameIndex(destArr,targetArr,i,j);
                j = 0;
            }
        if (j == targetLen)
            return i - j;
        else return -1;
    }

    public static int getSameIndex(char[] destArr, char[] targetArr, int i, int j) {//将匹配短数组第一个字符在长数组中的位置输出
        for (int k = i - j + 1; k <= i; k++)
            if (targetArr[0] == destArr[k])
                return k;
            return i - j + 1;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值