KMP算法

字符串匹配问题: 

  1. 有一个字符串 str1= "BBC ABCDAB ABCDABCDABDE",和一个子串 str2="ABCDABD"
  2. 现在要判断 str1 是否含有 str2, 如果存在,就返回第一次出现的位置, 如果没有,则返回-1

暴力匹配算法

如果用暴力匹配的思路,并假设现在str1匹配到 i 位置,子串str2匹配到 j 位置,则有:

  1. 如果当前字符匹配成功(即str1[i] == str2[j]),则i++,j++,继续匹配下一个字符
  2. 如果失配(即str1[i]! = str2[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0。
  3. 用暴力方法解决的话就会有大量的回溯,每次只移动一位,若是不匹配,移动到下一位接着判断,浪费了大量的时间。(不可行!)
  4. 暴力匹配算法实现
  5. package com.zx.ds.doubleTest;
    
    public class ViolenceMatch {
    
        public static int match(String s1,String s2){
            char c1[]=s1.toCharArray();
            char c2[]=s2.toCharArray();
    
            int i=0;
            int j=0;
            while(ipackage com.zx.ds.algorithm;
    
    import java.util.Arrays;
    
    public class KMP {
    
        //获取一个字符串的部分匹配表
        public static int[] kmpNext(String dest){
            //创建一个next 数组保存部分匹配值
            int next[]=new int[dest.length()];
            //如果字符串是长度为1 部分匹配值就是0
            next[0]=0;
    
            for(int i=1,j=0;i0&&dest.charAt(i)!=dest.charAt(j)){
                    j=next[j-1];
                }
    
                //当dest.charAt(i) == dest.charAt(j) 满足时,部分匹配值就是+1
                if(dest.charAt(i)==dest.charAt(j)){
                    j++;
                }
                next[i]=j;
            }
            return next;
        }
    
        /**
         *
         * @param str1 源字符串
         * @param str2 子串
         * @param next 部分匹配表, 是子串对应的部分匹配表
         * @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置
         */
        public static int match(String str1,String str2,int next[]){
            for(int i=0,j=0;i0&&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 void main(String[] args) {
            String str1 = "BBC ABCDAB ABCDABCDABDE";
            String str2 = "ABCDABD";
    
            int[] next = kmpNext("ABCDABD");
            System.out.println("next=" + Arrays.toString(next));
    
            System.out.println("index="+match(str1, str2, next));
            //next=[0, 0, 0, 0, 1, 2, 0]
            //index=15
        }
    }
    

    注:

    参考:

    很详尽KMP算法

你可能感兴趣的:(数据解构&算法)