zoukankan      html  css  js  c++  java
  • 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+"	"+c.length);
            System.out.println(str0+"	"+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
    ");
            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;
        }
  • 相关阅读:
    C++的高效从何而来2
    初体验ajax跨域
    ACM在线测评系统评测程序设计与实现
    高效GTD云工具 Manage Your Time
    HTTP 长连接
    使用avalon MVVM框架打造整一套jquery ui
    GhostDoc(注释生成工具)使用方法
    NUnit快速入门 笔记
    ETags
    nodejs + edge + ejs + c#
  • 原文地址:https://www.cnblogs.com/huangzhen22/p/14549116.html
Copyright © 2011-2022 走看看