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


Posted in Javascript onFebruary 03, 2018

本文实例讲述了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>3water.com</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 相关文章推荐
js下用层来实现select的title提示属性
Feb 23 Javascript
用js代码改变单选框选中状态的简单实例
Dec 18 Javascript
javascript 判断两个日期之差的示例代码
Sep 05 Javascript
js实现3d悬浮效果
Feb 16 Javascript
React Native 搭建开发环境的方法步骤
Oct 30 Javascript
vue父组件向子组件(props)传递数据的方法
Jan 02 Javascript
vue使用iframe嵌入网页的示例代码
Jun 09 Javascript
JavaScript原型对象原理与应用分析
Dec 27 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
Apr 07 Javascript
JavaScript 中判断变量是否为数字的示例代码
Oct 22 Javascript
一篇文章让你搞懂JavaScript 原型和原型链
Nov 23 Javascript
前端JS获取URL参数的4种方法总结
Apr 05 Javascript
Node.js实现mysql连接池使用事务自动回收连接的方法示例
Feb 03 #Javascript
js删除数组中的元素delete和splice的区别详解
Feb 03 #Javascript
JS删除数组里的某个元素方法
Feb 03 #Javascript
jQuery niceScroll滚动条错位问题的解决方法
Feb 03 #jQuery
JS实现百度搜索接口及链接功能实例代码
Feb 02 #Javascript
原生JS实现的双色球功能示例
Feb 02 #Javascript
jQuery实现的下雪动画效果示例【附源码下载】
Feb 02 #jQuery
You might like
alixixi runcode.asp的代码不错的应用
2007/08/08 Javascript
通用javascript脚本函数库 方便开发
2009/10/13 Javascript
jQuery对象与DOM对象之间的转换方法
2010/04/15 Javascript
Google 静态地图API实现代码
2010/11/19 Javascript
来自国外的30个基于jquery的Web下拉菜单
2012/06/22 Javascript
jquery win 7透明弹出层效果的简单代码
2013/08/06 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
js改变Iframe中Src的方法
2015/05/05 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
javascript实现延时显示提示框特效代码
2016/04/27 Javascript
当jquery ajax遇上401请求的解决方法
2016/05/19 Javascript
详解使用vue实现tab 切换操作
2017/07/03 Javascript
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
2020/02/06 NodeJs
ES6使用 Array.includes 处理多重条件用法实例分析
2020/03/02 Javascript
微信小程序开发(三):返回上一级页面并刷新操作示例【页面栈】
2020/06/01 Javascript
对vuex中store和$store的区别说明
2020/07/24 Javascript
[02:43]DOTA2亚洲邀请赛场馆攻略——带你走进东方体育中心
2018/03/19 DOTA
Python3中多线程编程的队列运作示例
2015/04/16 Python
Python基于sklearn库的分类算法简单应用示例
2018/07/09 Python
python执行CMD指令,并获取返回的方法
2018/12/19 Python
python 画出使用分类器得到的决策边界
2019/08/21 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
2020/02/29 Python
python中pyplot基础图标函数整理
2020/11/10 Python
Python爬虫爬取有道实现翻译功能
2020/11/27 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
一张图片能隐含千言万语之隐藏你的程序代码
2012/12/13 HTML / CSS
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
编辑个人求职信范文
2013/09/21 职场文书
医药营销个人求职信范文
2014/02/07 职场文书
单位承诺书格式
2014/05/21 职场文书
护理专业自荐书
2014/06/04 职场文书
环保标语大全
2014/06/12 职场文书
检察院院长群众路线教育实践活动个人整改措施
2014/10/04 职场文书
指导教师推荐意见
2015/06/05 职场文书
道士塔读书笔记
2015/06/30 职场文书
python可视化之颜色映射详解
2021/09/15 Python