欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-02 14:36:11
本文实例讲述了javascript实现求最大公共子串的方法。分享给大家供大家参考,具体如下: 求最大公共子串,常见的做法是使用矩阵。假设有字符串:abcdefg和字符串a...

本文实例讲述了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程序设计有所帮助。