JavaScript实现求最大公共子串的方法

本文实例讲述了JavaScript实现求最大公共子串的方法。分享给大家供大家参考,具体如下:

求最大公共子串,常见的做法是使用矩阵。假设有字符串:abcdefg和字符串abcd,则可构成如下表所示矩阵。

a b c d e f g
a 1 0 0 0 0 0 0
b 0 1 0 0 0 0 0
c 0 0 1 0 0 0 0
d 0 0 0 1 0 0 0

对两个字符串的每一项都进行比较,若匹配则该项为1,不匹配则为0。然后求出对角线最长为1的那一段序列,即为最大公共子串。看上面的分开,似乎得使用二维数组了,在两个字符串都较大的情况下不是很划算,是否可以进一步优化?

可以,需要改变一下策略,如果该项匹配,则该项的值为再设为1,而是其对角线a[i-1, j-1](i > 1 && j > 1)的值+1,这样便可以只使用一个一维数组。

以一个字符串作为“行”,另一个作为“列”,比较两个字符串各项的值,用另外一个变量记录数组的最大值和字符串的起始位置。代码如下:

function LCS(str1, str2) {
 if (str1 === "" || str2 === "") {
  return "";
 }
 var len1 = str1.length;
 var len2 = str2.length;
 var a = new Array(len1);
 var maxLen = 0;
 var maxPos = 0;
 for (var i = 0; i < len1; i++) { //行
  for (var j = len2 - 1; j >= 0; j--) {//列
   if (str1.charAt(j) == str2.charAt(i)) {
    if (i === 0 || j === 0) {
     a[j] = 1;
    } else {
     a[j] = a[j - 1] + 1;
    }
   } else {
    a[j] = 0;
   }
   if (a[j] > maxLen) {
    maxLen = a[j];
    maxPos = j;
   }
  }
 }
 return str1.substr(maxPos - maxLen + 1, maxLen);
}

但代码其实并不是最优的,为什么?因为上面的写法必须等待两层循环都完成。有没有相对更快一些的方法呢?

设有字符串a、b,其长度分别为len1、len2,其公共字子串一定是 <= Math.min(len1, len2),而且子串必定连续,且一定是a、b的子串。

function findMaxSubStr(s1,s2){
 var str= "",
  L1=s1.length,
  L2=s2.length;
 if (L1>L2){
  var s3=s1;
  s1=s2;
  s2=s3;
  s3 = null;
  L1=s2.length;
  L2 = s1.length;
 }
 for (var i=L1; i > 0; i--) {
  for (var j= 0; j <= L2 - i && j < L1; j++){
   str = s1.substr(j, i);
   if (s2.indexOf(str) >= 0) {
    return str;
   }
  }
 }
 return "";
}

先比较s1、s2的长度,然后取较短的字符串作为。substr(idex, len),所以拿较短的串取其子串,然后判断它是否在较长的字符串中存在,如果存中则直接返回,否则再取下一位。

完整示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>www.jb51.net</title>
 <style type='text/css'>
 body {background-color:#fff;}
 </style>
 </head>
 <body>
<script type='text/javascript'>
function LCS(str1, str2) {
 if (str1 === "" || str2 === "") {
 return "";
 }
 var len1 = str1.length;
 var len2 = str2.length;
 var a = new Array(len1);
 var maxLen = 0;
 var maxPos = 0;
 for (var i = 0; i < len1; i++) { //行
 for (var j = len2 - 1; j >= 0; j--) {//列
 if (str1.charAt(j) == str2.charAt(i)) {
 if (i === 0 || j === 0) {
  a[j] = 1;
 } else {
  a[j] = a[j - 1] + 1;
 }
 } else {
 a[j] = 0;
 }
 if (a[j] > maxLen) {
 maxLen = a[j];
 maxPos = j;
 }
 }
 }
 return str1.substr(maxPos - maxLen + 1, maxLen);
}
function findMaxSubStr(s1,s2){
 var str= "",
 L1=s1.length,
 L2=s2.length;
 if (L1>L2) {
 var s3=s1;
 s1=s2;
 s2=s3;
 s3 = null;
 L1=s2.length;
 L2 = s1.length;
 }
 for (var i=L1; i > 0; i--) {
 for (var j= 0; j <= L2 - i && j < L1; j++){
   str = s1.substr(j, i);
   if (s2.indexOf(str) >= 0) {
 return str;
  }
  }
 }
 return "";
}
 !(function() {
 var tmpArr = [];
 for (var i = 97; i < 97 + 26; i++) {
 tmpArr.push(String.fromCharCode(i));
 }
 var s2 = tmpArr.join("");
 tmpArr.sort(function() {return Math.random() > 0.7;});
 var s1 = new Array(600).join(tmpArr.join(""));
 var date = getNow();
 alert( "消耗时间:" + (getNow() - date) + "秒 " + LCS(s1, s2));
 date = getNow();
 alert( "消耗时间:" + (getNow() - date) + "秒 " + findMaxSubStr(s1, s2) );
 })();
function getNow() {
 return new Date().getTime();
}
</script>
 </body>
</html>

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

您可能感兴趣的文章:

  • JavaScript自定义函数实现查找两个字符串最长公共子串的方法
  • js判断一个字符串是否包含一个子串的方法
  • js判断出两个字符串最大子串的函数实现方法
  • JS使用正则表达式找出最长连续子串长度
  • 在JavaScript中访问字符串的子串
  • JavaScript检查子字符串是否在字符串中的方法
  • JavaScript判断一个字符串是否包含指定子字符串的方法
  • javascript查找字符串中出现最多的字符和次数的小例子
  • js中通过split函数分割字符串成数组小例子
  • JavaScript计算字符串中每个字符出现次数的小例子
  • javascript下搜索子字符串的的实现代码(我们修正版)
(0)

相关推荐

  • js判断一个字符串是否包含一个子串的方法

    本文实例讲述了js判断一个字符串是否包含一个子串的方法.分享给大家供大家参考.具体如下: 在我们前端日常开发中,经常会遇到判断一个字符串中是否包含某个子串,这里我们将去探究一些解决此种需求的方法以及正确的使用它们.理想情况下,我们要找的是一个能匹配我们的目的(if x contains y)的方法,并返回true或false. 一.String.prototype.indexOf和String.prototype.lastIndexOf 这两个方法,可能是我们最容易想到的,如果包含子串,则返回大

  • javascript查找字符串中出现最多的字符和次数的小例子

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&qu

  • JavaScript检查子字符串是否在字符串中的方法

    本文实例讲述了JavaScript检查子字符串是否在字符串中的方法.分享给大家供大家参考,具体如下: var strnew="Hello Raghu How are u" //Checking existence in entire string if(strnew.indexOf("Raghu") != -1 ) { alert("Exists"); } /* Checking existence at the end of string Fo

  • javascript下搜索子字符串的的实现代码(脚本之家修正版)

    例如有这么一个字符串<img src='test' alt=123>xtxtxt<img src='test' alt=321>1221<img src='test' alt=yes>,我要从中找出所以alt的值,同时还有非标签中的值,想这个例子中,就是要搜索出123xtxtxt3211221yes这个结果来 ,还有一点就是 原字符串是不确定的,是由用户输入的 test //搜索出所有alt的值和innerHTML的值 var tmp=""; var

  • 在JavaScript中访问字符串的子串

    使用substring()或slice()方法(NN4+, IE4+),下面说明它们的具体用法. substring()的原型为: string.substring(from, to) 第一个参数from指定了子字符串在原字符串中的起始位置(基于0的索引):第二个参数to是可选的,它指定了子字符串在原字符串的结束位置(基于0的索引),一般情况下,它应比from大,如果它被省略,那么子字符串将一直到原字符串的结尾处. 如果参数from不小心比参数to大了会怎样?JavaScript会自动调解子字符

  • js判断出两个字符串最大子串的函数实现方法

    如下所示: <!DOCTYPE html> <html> <head> <title></title> </head> <script type="text/javascript"> function search(str1,str2) { var i=j=k=a=jk=kk=0; var m=str1.length; var n=str2.length; var index=0; var maxlen

  • JavaScript计算字符串中每个字符出现次数的小例子

    代码如下: 复制代码 代码如下: function numInstring(str){    str=str.replace(/ /ig,"");    var strArr=str.split("");    var result=[],beforeLength,afterLength,reg;    for(var i=0;i<strArr.length;i++){        if(str.indexOf(strArr[i])!=-1){       

  • JS使用正则表达式找出最长连续子串长度

    废话不多说了,直接给大家贴代码了,具体代码如下所示: function maxLenStr(str){ var len = 0, max_len = 0; var reg = new RegExp("(.)\\1{1,}","g"); var res = reg.exec(str); while(res != null){ len = res[0].length; if(max_len < len){ max_len = len; } res = reg.ex

  • JavaScript自定义函数实现查找两个字符串最长公共子串的方法

    本文实例讲述了JavaScript自定义函数实现查找两个字符串最长公共子串的方法.分享给大家供大家参考,具体如下: //查找两个字符串的最长公共子串 function findSubStr(s1,s2){ var S=sstr= "" ,L1=s1.length,L2=s2.length; if (L1>L2){ var s3=s1;s1=s2,s2=s3,L1=s2.length;} for ( var j=L1;j> 0 ;j--) for ( var i= 0 ;i&

  • js中通过split函数分割字符串成数组小例子

    复制代码 代码如下: <script language="javascript"> str="2,2,3,5,6,6"; //这是一字符串 var strs= new Array(); //定义一数组 strs=str.split(","); //字符分割 for (i=0;i<strs.length ;i++ ) { document.write(strs[i]+"<br/>"); //分割后的

  • JavaScript判断一个字符串是否包含指定子字符串的方法

    本文实例讲述了JavaScript判断一个字符串是否包含指定子字符串的方法.分享给大家供大家参考.具体分析如下: 下面的JS代码,为String对象定义了一个contains方法用于判断字符串是否包含子字符串,非常有用. if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(obj, start) { for (var i = (start || 0), j = this.length; i < j; i++) {

随机推荐