字符串匹配算法

来源:互联网 发布:淘宝怎么打开淘口令 编辑:程序博客网 时间:2024/06/01 22:59
/** * KMP算法用来处理字符串匹配问题 * 原理介绍:找到匹配失败时的最合适的回退位置,而不是简单的回退到子串的第一个字符(常规的枚举查找方式,是简单的回退到子串的第一个字符),即可提高查找的效率. * 因此为了找到这个合适的位置,先对子串预处理,从而得到一个回退位置的数组. * */public class KMP {/**  * 对子串加以预处理,从而找到匹配失败时子串回退的位置,此过程是子串的自我匹配过程,类似于KMP过程  * @return  */ public static int[] preProcess(char [] B) {  int size = B.length;  int[] P = new int[size];  P[0]=0;  int j=0;  //每循环一次,就会找到子串第i个字符匹配失败时,子串的一个回退位置  for(int i=1;i<size;i++){   while(j>0 && B[j]!=B[i]){    j=P[j];   }   //只有当子串中含有重复字符时,回退的位置才会被优化   if(B[j]==B[i]){    j++;   }   //找到一个回退位置j,把其放入P[i]中   P[i]=j;  }  return P; }  /**  * KMP实现  */ public static void kmp(String parStr, String subStr) {  int subSize = subStr.length();  int parSize = parStr.length();  char[] B = subStr.toCharArray();  char[] A = parStr.toCharArray();  int[] P = preProcess(B);  int j=0;  int k =0;  for(int i=0;i<parSize;i++){  //当子串的第j个字符(B[j])不等于源串的第i个字符(A[i])时,对B字符串进行回退,回退到A[i-j+ 1..i]与B[1..j]相等  while(j>0 && B[j]!=A[i]){   //找到合适的回退位置  j=P[j-1];  }  //当子串的第j个字符(B[j])匹配源串的第i个字符(A[i])时,j加1  if(B[j]==A[i]){  j++;  }  //输出匹配结果,并且让比较继续下去  if(j==subSize){  j=P[j-1];  k++;  System.out.printf("Find subString '%s' at %d\n",subStr,i-subSize+1);  }  }  System.out.printf("Totally found %d times for '%s'.\n\n",k,subStr); }public static void main(String[] args) {  kmp("abcdeg, abcdeh, abcdef","abcdef");  //回退位置数组为P[0, 0, 1, 2, 3, 4]  kmp("Test ititi ititit! Test ititit","ititit");}}


原创粉丝点击