字符串匹配---KMP

/*
ababababababb abababb
*/

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String source = sc.next();
        String pattern = sc.next();
        sc.close();
        plain(source, pattern);
        KMP(source, pattern);
    }
    //朴素模式,一位一位的比较,丢弃了之前失败的信息
    private static void plain(String source, String pattern) {
        int res=0;
        int sourceLen=source.length();
        int patternLen=pattern.length();
        for(int i=0;i<=(sourceLen-patternLen);i++){
            res++;
            String str=source.substring(i, i+patternLen);
            if(str.equals(pattern)){
                System.out.println("朴素模式:匹配成功");
                break;
            }
        }
        System.out.println("朴素模式:一共匹配"+res+"次");
    }

    //KMP算法实现
    private static void KMP(String source, String pattern) {
        int[] next = makeNext(pattern);
        int res=0;
        int sourceLen=source.length();
        int patternLen=pattern.length();
        int i = 0;
        while(i <= sourceLen-patternLen) {
            res++;
            String str=source.substring(i, i+patternLen);//要比较的字符串
            System.out.println(str);
            int count=getNext(pattern, str, next);
            System.out.println("移动"+count+"步");
            if(count==0){
                System.out.println("KMP:匹配成功");
                break;
            }
            i=i+count;
        }
        System.out.println("KMP:一共匹配"+res+"次数");
    }

    //得到下一次要移动的次数
    private static int getNext(String pattern,String str,int[] next) {
        int n = pattern.length();
        char v1[] = str.toCharArray();
        char v2[] = pattern.toCharArray();
        for(int x = 0; n != 0; x++,n--) {
            if (v1[x] != v2[x]){
                if(x==0){
                    return 1;//如果第一个不相同,移动1步
                }
                return x-next[x-1];//x:第一次出现不同的索引的位置,即j
            }
        }
        return 0;
    }
    //得到next数组。next[i]即前i个字符前缀和后缀共有元素最长长度
    private static int[] makeNext(String pattern){
        char[] P = pattern.toCharArray();
        int next[] = new int[P.length];
        next[0] = 0;
        for (int q = 1,k = 0; q < P.length; ++q){
            while(k > 0 && P[q] != P[k]) {
                k = next[k-1];
            }
            if (P[q] == P[k]){
                k++;
            }
            next[q] = k;
        }
        for(int a : next) {
            System.out.print(a+" ");
        }System.out.println();
        return next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值