前言:在博客园中看到了阮一锋讲解KMP算法的文章以及园中另外一位博友写的JS版本的KMP算法,根据自己的理解,在这位博友的基础上改进了下。
代码如下:
1 /** 2 * 生成部分匹配表 3 */ 4 function kmpGetPartMatchTable(targetStr){ 5 var aPartMatchTable = []; 6 var tmpCompareLen = 0; 7 var tmpPartMatchVal = 0; 8 var prefix,suffix;//匹配串前缀,后缀 9 for (var i = 0, j = targetStr.length; i < j; i++){ 10 if (i == 0){ 11 aPartMatchTable[i] = 0; 12 continue; 13 } 14 tmpCompareLen = i; //匹配串前缀,后缀最大长度 15 tmpPartMatchVal = 0; 16 for (;tmpCompareLen > 0; tmpCompareLen--){ 17 prefix = targetStr.substr(0,tmpCompareLen); 18 suffix = targetStr.substr(i-tmpCompareLen+1,tmpCompareLen); 19 if (prefix == suffix){ //找到匹配串前缀,后缀最长的共有元素 20 tmpPartMatchVal = prefix.length; //部分匹配值为:匹配串前缀,后缀最长的共有元素的长度 21 break; 22 } 23 } 24 aPartMatchTable[i] = tmpPartMatchVal; 25 } 26 return aPartMatchTable; 27 } 28 29 /** 30 * KMP算法 查找字符串 31 */ 32 function KMP(sourceStr,targetStr){ 33 var partMatchValue = kmpGetPartMatchTable(targetStr); //部分匹配表 34 var result = false; 35 var i,j,m,n; 36 n = targetStr.length; 37 for(i=0,j=sourceStr.length;i<j;i++){ 38 for(var m=0;m<n;m++){ 39 if(targetStr.charAt(m) != sourceStr.charAt(i+m)){ 40 if ( (m > 0) && (partMatchValue[m-1] > 0) ){ 41 i += (m-partMatchValue[m-1]-1); //设置外层循环开始位置 42 } 43 break; 44 } 45 } 46 if (m == n){ 47 result = true; 48 break; 49 } 50 } 51 return result; 52 } 53 s = "BBC ABCDAB ABCDABCDABDE"; 54 t = "ABCDABD"; 55 console.log( KMP(s,t) );
参考链接
http://news.cnblogs.com/n/176771/
http://www.cnblogs.com/artwl/archive/2013/05/02/3054434.html