KMP

代码来源于灵茶山艾府

模式串自匹配

int[] calculateMaxMatchLengths(String pattern) {
        //子字符串匹配最大长度结果集
       int[] maxMatchLengths=new int[pattern.length()];
       //当前子字符串匹配最大长度
       int maxLength=0;
       //遍历
       for(int i=1;i<pattern.length();i++){
                //maxlength代表当前匹配最大长度的下一个字符,与新加入的字符做对比
                //,看是否相等,如果不相等,则比较i-2与当前加入字符2比较
                //如果maxlength=0,说明此子字符串序列中没有匹配前后缀字符串,那么让新加入的字符作为后缀第一个与前缀第一个作比较
                //如果相等,最大长度+1
                while(maxLength!=0&&pattern.charAt(maxLength)!=pattern.charAt(i)){
                    //maxLength代表i-1的最大匹配长度,maxlength-1就是i-2的最大匹配长度,因为maxlength每次增加幅度都是1,
                    //所以减一代表上一个序列的结果
                    //迭代到上一个序列作比较,如果等于0直接比较第一个与最后一个,不然继续迭代
                    maxLength=maxMatchLengths[maxLength-1];
                }
                //如果相等,最大匹配长度+1,并存到结果集里
                if(pattern.charAt(maxLength)==pattern.charAt(i))
                maxLength++;
                maxMatchLengths[i]=maxLength;
       }
       //循环结束,返回结果集
       return maxMatchLengths;
    }

查询位置

List<Integer> search(String text, String pattern) {
    List<Integer> positions=new ArrayList<>();
    int[] maxs=calculateMaxMatchLengths(pattern);
    int count=0;
    for(int i=0;i<text.length();i++){
        while(count>0&&text.charAt(i)!=pattern.charAt(count)){
            count=maxs[count-1];
        }
        if(text.charAt(i)==pattern.charAt(count))
        count++;
        if(count==pattern.length()){
            positions.add(i-count+1);
            count=maxs[count-1];
        }

    }
    //记录匹配字符个数
        //如果有不匹配的字符,匹配字符串移动匹配的子字符串的最大匹配长度
        //字符匹配,个数加一
        //个数等于匹配字符长度,说明找到字符串,将字符串起始位置加入结果集,匹配字符串
    return positions;
}
posted @ 2020-05-29 22:30  Kotonoha  阅读(15)  评论(1编辑  收藏