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中arguments对象详解
Oct 22 Javascript
浅谈 javascript 事件处理
Jan 04 Javascript
通过JS判断联网类型和连接状态的实现代码
Apr 01 Javascript
jQuery实现伸展与合拢panel的方法
Apr 30 Javascript
bootstrap实现的自适应页面简单应用示例
Mar 09 Javascript
JS实现动态给标签控件添加事件的方法示例
May 13 Javascript
vue 不使用select实现下拉框功能(推荐)
May 17 Javascript
如何在js代码中消灭for循环实例详解
Jul 29 Javascript
node.js遍历目录的方法示例
Aug 01 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
Sep 11 Javascript
基于javascript的拖拽类封装详解
Apr 19 Javascript
JavaScript读取本地文件常用方法流程解析
Oct 12 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
ninety plus是什么?ninety plus咖啡好吗?
2021/03/04 新手入门
PHP删除非空目录的函数代码小结
2013/02/28 PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
2013/06/18 PHP
Yii2实现多域名跨域同步登录退出
2017/02/04 PHP
PHP 7.0新增加的特性介绍
2017/06/08 PHP
Yii 2.0实现联表查询加搜索分页的方法示例
2017/08/02 PHP
利用Homestead快速运行一个Laravel项目的方法详解
2017/11/14 PHP
背景音乐每次刷新都可以自动更换
2007/02/01 Javascript
js滚动条多种样式,推荐
2007/02/05 Javascript
js DOM 元素ID就是全局变量
2012/09/20 Javascript
载入jQuery库的最佳方法详细说明及实现代码
2012/12/28 Javascript
jquery实现的美女拼图游戏实例
2015/05/04 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
基于JS实现无缝滚动思路及代码分享
2016/06/07 Javascript
Javascript获取随机数的实现方法
2016/06/22 Javascript
扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
2017/02/21 Javascript
Java与JavaScript中判断两字符串是否相等的区别
2017/03/13 Javascript
vue.js指令和组件详细介绍及实例
2017/04/06 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
2018/09/30 Javascript
JS中appendChild追加子节点无效的解决方法
2018/10/14 Javascript
浅谈javascript错误处理
2019/08/11 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
2019/09/24 Javascript
node使用request请求的方法
2019/12/20 Javascript
Python设置默认编码为utf8的方法
2016/07/01 Python
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
Django项目使用ckeditor详解(不使用admin)
2019/12/17 Python
基于spring boot 日志(logback)报错的解决方式
2020/02/20 Python
简述python&amp;pytorch 随机种子的实现
2020/10/07 Python
美国批发零售网站:GearXS
2016/07/26 全球购物
科颜氏美国官网:Kiehl’s美国
2017/01/31 全球购物
应届生服装设计自我评价
2013/09/20 职场文书
2014年小学元旦活动方案
2014/02/12 职场文书
公司办公室岗位职责
2014/03/19 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
简易离婚协议书范本
2014/10/24 职场文书