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 相关文章推荐
bcastr2.0 通用的图片浏览器
Nov 22 Javascript
仅用[]()+!等符号就足以实现几乎任意Javascript代码
Mar 01 Javascript
登陆成功后自动计算秒数执行跳转
Jan 23 Javascript
JS判断文本框内容改变事件的简单实例
Mar 07 Javascript
使用原生js写的一个简单slider
Apr 29 Javascript
JS+CSS简单树形菜单实现方法
Sep 12 Javascript
JavaScript的函数式编程基础指南
Mar 19 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
Jun 03 Javascript
Three.js实现绘制字体模型示例代码
Sep 26 Javascript
微信小程序自定义底部弹出框
Nov 16 Javascript
JavaScript实现简单验证码
Aug 24 Javascript
AJAX实现省市县三级联动效果
Oct 16 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
第一节--面向对象编程
2006/11/16 PHP
php读取文件内容的几种方法详解
2013/06/26 PHP
javascript实现仿银行密码输入框效果的代码
2007/12/13 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
2014/04/08 Javascript
javascript常用方法汇总
2014/12/02 Javascript
js实现鼠标悬浮给图片加边框的方法
2015/01/30 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
2015/08/06 Javascript
JavaScript实现使用Canvas绘制图形的基本教程
2016/10/27 Javascript
微信小程序 页面跳转传参详解
2016/10/28 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
解决JS外部文件中文注释出现乱码问题
2017/07/09 Javascript
JQuery 又谈ajax局部刷新
2017/11/27 jQuery
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
JS原型prototype和__proto__用法实例分析
2020/03/14 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
vue中实现图片压缩 file文件的方法
2020/05/28 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
PyQt5每天必学之切换按钮
2020/08/20 Python
详解Python爬取并下载《电影天堂》3千多部电影
2019/04/26 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
CSS3教程(9):设置RGB颜色
2009/04/02 HTML / CSS
携程旅行网:中国领先的在线旅行服务公司
2017/02/17 全球购物
建筑学推荐信
2013/11/03 职场文书
化学教师自荐信范文
2013/12/28 职场文书
服务行业口号
2014/06/11 职场文书
反对形式主义、官僚主义、享乐主义和奢靡之风整改措施
2014/09/17 职场文书
离婚被告代理词
2015/05/23 职场文书
go web 预防跨站脚本的实现方式
2021/06/11 Golang
Python虚拟环境virtualenv是如何使用的
2021/06/20 Python
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP
Python Pytorch查询图像的特征从集合或数据库中查找图像
2022/04/09 Python
Python面试不修改数组找出重复的数字
2022/05/20 Python