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 相关文章推荐
javascript开发技术大全 第4章 直接量与字符集
Jul 03 Javascript
鼠标滑过出现预览的大图提示效果
Feb 26 Javascript
JavaScript中的类与实例实现方法
Jan 23 Javascript
javascript对象的相关操作小结
May 16 Javascript
JS实现table表格数据排序功能(可支持动态数据+分页效果)
May 26 Javascript
artDialog+plupload实现多文件上传
Jul 19 Javascript
javascript的函数劫持浅析
Sep 26 Javascript
Bootstrap表单控件使用方法详解
Jan 11 Javascript
webpack里使用jquery.mCustomScrollbar插件的方法
May 30 jQuery
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 Javascript
vue vant中picker组件的使用
Nov 03 Javascript
JS 4个超级实用的小技巧 提升开发效率
Oct 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
php初学者写及时补给skype用户充话费的小程序
2008/11/02 PHP
百度工程师讲PHP函数的实现原理及性能分析(一)
2015/05/13 PHP
PHP 自动加载的简单实现(推荐)
2016/08/12 PHP
thinkPHP内置字符串截取函数用法详解
2016/11/15 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
2020/04/23 PHP
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
事件模型在各浏览器中存在差异
2010/10/20 Javascript
HTML Dom与Css控制方法
2010/10/25 Javascript
jQuery结合PHP+MySQL实现二级联动下拉列表[实例]
2011/11/15 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
手机端网页点击链接触发自动拨打或保存电话的示例代码
2014/08/15 Javascript
全面了解javascript三元运算符
2016/06/27 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
jQuery实现一个简单的验证码功能
2017/06/26 jQuery
解决vue2.x中数据渲染以及vuex缓存的问题
2017/07/13 Javascript
angular使用bootstrap方法手动启动的实例代码
2017/07/18 Javascript
angular2中使用第三方js库的实例
2018/02/26 Javascript
javascript中call()、apply()的区别
2019/03/21 Javascript
vue.js iview打包上线后字体图标不显示解决办法
2020/01/20 Javascript
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
原生JS实现拖拽效果
2020/12/04 Javascript
[47:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python获取文件所在目录和文件名的方法
2017/01/12 Python
Flask 让jsonify返回的json串支持中文显示的方法
2018/03/26 Python
python 读文件,然后转化为矩阵的实例
2018/04/23 Python
numpy求平均值的维度设定的例子
2019/08/24 Python
python中pathlib模块的基本用法与总结
2020/08/17 Python
Python爬虫实战案例之爬取喜马拉雅音频数据详解
2020/12/07 Python
python自动生成sql语句的脚本
2021/02/24 Python
新西兰航空中国官网:Air New Zealand China
2018/07/24 全球购物
餐饮业经理竞聘演讲稿
2014/01/14 职场文书
摄影专业毕业生求职信
2014/03/13 职场文书
汇报材料怎么写
2014/12/30 职场文书
幼师小班个人总结
2015/02/12 职场文书
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python