赞
踩
第一步:用str1的第一个字符和str2的第一个字符去比较,不符合,关键词向后移动一位
第二步:重复步骤一,继续向后移动
第三步:一直重复直到str1有一个字符与str2的第一个字符符合为止
第四步:接着比较字符串和搜索词的下一个字符,是否还是符合,符合直接比,不符合进行下一步
第五步:此时如果继续重复步骤一,会出现“暴力匹配”,也就是继续一个一个往下比较,KMP算法思想就是利用已经知道的信息,不要把"搜索位置"拉回到以前,而是继续后移。
ABCDAB
后面这些公共部分,所以对str2计算出一张一个叫 部分匹配的概念。由上面的步骤,我们有一个问题,就是怎么样去确定到底应该向后移动多少步骤,由此引出部分匹配表的概念
前缀 与 后缀
"bread"
b,br,bre,brea
read,ead,ad,d
部分匹配表
public class KMPAlogrithm { public static void main(String[] args) { String str1 ="BBC ABCDAB ABCDABCDABDE"; String str2 ="ABCDABD"; //获取到一个字符串(字串)的部分匹配值 int []next =kmpNext("ABCDABD");//[0,1] int result = kmpSercach(st1,str2,next []); System.out.println("result = "+result); } //写出kmp搜索算法 /* * str1 原字符串 * str2 子串 * next 部分匹配表 * @return 如果是-1,就是没有匹配到,否则返回第一个匹配的位置 * */ public static int kmpSerach(String str1,String str2,int[] next){ //遍历 for (int i = 0,j=0; i < str1.length(); i++) { //需要处理,当str1.charAt(i) != str2.charAt(j) //kmp算法核心点 while ( j > 0 &&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 int[] kmpNext(String dest){ //创建一个next数组保存部分匹配值 int[] next = new int[dest.length()]; next[0] = 0;//如果字符串是长度为1部分匹配值就是0 for (int i = 1,j=0; i < dest.length(); i++) { //当dest.charAt(i)!=dest.charAt(j),需要从next[j-1]获取新的j //直到发现dest.charAt(i) ==dest.charAt(j)成立时候退出 //kmp算法核心点 while ( j > 0&&dest.charAt(i)!=dest.charAt(j)){ j=next[j-1]; } //当这个条件满足时,部分匹配值就加1 if (dest.charAt(i)==dest.charAt(j)){ j++; } next[i] = j; } return next; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。