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 相关文章推荐
为数据添加append,remove功能
Oct 03 Javascript
use jscript List Installed Software
Jun 11 Javascript
Javascript字符串浏览器兼容问题分析
Dec 01 Javascript
JQuery中使用on方法绑定hover事件实例
Dec 09 Javascript
node.js中使用socket.io的方法
Dec 15 Javascript
jquery实现表单验证并阻止非法提交
Jul 09 Javascript
纯javascript实现图片延时加载方法
Aug 21 Javascript
prototype框架中美元符号$用法分析
Jan 22 Javascript
js友好的时间返回函数
Aug 24 Javascript
JS判断指定dom元素是否在屏幕内的方法实例
Jan 23 Javascript
使用Require.js封装原生js轮播图的实现代码
Jun 15 Javascript
react学习笔记之state以及setState的使用
Dec 07 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 Undefined index和Undefined variable的解决方法
2008/03/27 PHP
php 文件状态缓存带来的问题
2008/12/14 PHP
PHP按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
php通过两层过滤获取留言内容的方法
2016/07/11 PHP
php文件上传、下载和删除示例
2020/08/28 PHP
JQuery each()函数如何优化循环DOM结构的性能
2012/12/10 Javascript
js猜数字小游戏的简单实现代码
2013/07/02 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
js使用原型对象(prototype)需要注意的地方
2017/08/28 Javascript
vue项目中用cdn优化的方法
2018/01/03 Javascript
5分钟快速掌握JS中var、let和const的异同
2018/09/19 Javascript
JavaScript多种页面刷新方法小结
2019/04/04 Javascript
浅谈JS中this在各个场景下的指向
2019/08/14 Javascript
Layui实现数据表格默认全部显示(不要分页)
2019/10/26 Javascript
python GUI实例学习
2017/11/21 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
详解Django的model查询操作与查询性能优化
2018/10/16 Python
浅谈Python爬虫基本套路
2019/03/25 Python
python绘制双Y轴折线图以及单Y轴双变量柱状图的实例
2019/07/08 Python
基于django 的orm中非主键自增的实现方式
2020/05/18 Python
Python多线程正确用法实例解析
2020/05/30 Python
安装pyinstaller遇到的各种问题(小结)
2020/11/20 Python
Pycharm在指定目录下生成文件和删除文件的实现
2020/12/28 Python
C#面试题
2016/05/06 面试题
团购业务员岗位职责
2014/03/15 职场文书
大学奖学金获奖感言
2014/08/15 职场文书
物流管理专业推荐信
2014/09/06 职场文书
习总书记三严三实学习心得体会
2014/10/13 职场文书
整改落实自查报告
2014/11/05 职场文书
一年级数学下册复习计划
2015/01/17 职场文书
2015年教师节慰问信
2015/03/23 职场文书
入党积极分子培养人意见
2015/06/02 职场文书
vue-cropper插件实现图片截取上传组件封装
2021/05/27 Vue.js
IDEA2021.2配置docker如何将springboot项目打成镜像一键发布部署
2021/09/25 Java/Android