KMP算法实现字符串匹配

* 有一个字符串 str = "be bed been bean better beach" 和一个子串 str0 = "bean"
* 判断 str 是否含有 str0,有则返回第一次出现的位置,没有返回-1
* 思路
* 循环主串每个字符 i 循环主串每个字符j
* 如果当前字符串匹配成功即str[i]==str[j],则i++,j++匹配下一个
* 如果匹配挫败 则将j置0,i =i-j+1,即匹配失败的后一个位置开始重新匹配
暴力匹配代码实现

/**
 * 字符串匹配
 * 有一个字符串 str = "be bed been bean better beach" 和一个子串 str0 = "bean"
 * 判断 str 是否含有 str0,有则返回第一次出现的位置,没有返回-1
 * 思路
 * 循环主串每个字符 i 循环主串每个字符j
 * 如果当前字符串匹配成功即str[i]==str[j],则i++,j++匹配下一个
 * 如果匹配挫败  则将j置0,i =i-j+1,即匹配失败的后一个位置开始重新匹配
 * 效率低:每次只移动一位,匹配失败就移到下一位接着判断,浪费时间。
 */
public class StringViolentMatchDemo {
    public static void main(String[] args) {
        String str = "be bed been bean bank better beach";
        String str0 ="been";

        char[] c = str.toCharArray();
        char[] c0 =str0.toCharArray();
        System.out.println(str+"\t"+c.length);
        System.out.println(str0+"\t"+c0.length);
        int i=0;
        int j=0;
        while (i<c.length&&j<c0.length){
            if(c[i]==c0[j]){
                i++;
                j++;
            }
            else{
                i=i-j+1;
                j=0;
            }
        }
        if(j==c0.length){
            System.out.println(i-j);
        }
        else{
            System.out.println(-1);
        }
    }
}

KMP匹配

利用之前判断过信息,通过next数组保存子串中前后最长共子序列的长度,每次回溯时,通过next数组找到,越过前面匹配过的位置,节省大量时间

部分匹配表的产生

 

 代码实部分匹配值数组

private static  int [] next(String str){
        int [] arr = new int[str.length()];
        arr[0]=0;
        for(int i=1,j=0;i<arr.length;i++){
            int vi =str.charAt(i);
            int vj =str.charAt(j);
            char si =(char)vi;
            char sj =(char)vj;
            while (j>0&&vi!=vj){
                j=arr[j-1];
            }
            if(vi==vj){
                j++;
            }
            arr[i]=j;
        }
        return arr;
    }

KMP利用部分匹配值实现字符串匹配

public static void main(String[] args) {
        //测试部分匹配值表
        String strTest ="ABCDABD";
        System.out.println(strTest+" 是否为 0 0  0 0  1 2  0\n");
        int [] next =next(strTest);
        System.out.println(Arrays.toString(next));
        //测试KMP算法
        String str = "be bed been bean bank better bean beach";
        String str0 ="been";
        int position = doKMPStringMatch(str,str0);
        System.out.println(str0+"在"+str+"中首次出来的位置为:"+position);
    }
    private static int doKMPStringMatch(String str,String s){
        //计算部分匹配值
        int [] next = next(s);
        System.out.println(s+" 的部分匹配值:"+Arrays.toString(next));
        for (int i = 0,j=0; i < str.length(); i++) {
            int vi =str.charAt(i);
            int vj=s.charAt(j);
            while (j>0&&vi!=vj){
                j=next[j-1];
            }
            if(vi==vj){
                j++;
            }
            if(j==s.length()){
                return i-j+1;
            }
        }
        return -1;
    }

 

posted @ 2021-03-17 14:19  黄忠  阅读(95)  评论(0编辑  收藏  举报