前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript求最大公共子串

JavaScript求最大公共子串

作者头像
meteoric
发布2019-02-25 16:46:01
8470
发布2019-02-25 16:46:01
举报
文章被收录于专栏:游戏杂谈游戏杂谈

求最大公共子串,常见的做法是使用矩阵。

假设有字符串: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,这样便可以只使用一个一维数组。

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

代码如下:

代码语言: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);
}

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

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

代码语言:javascript
复制
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>LCS</title> <style type='text/css'> body {background-color:#fff;} </style> </head> <body> </body> </html> 预览代码

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-06-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档