免费刷金币,请点击这里
TE社区 > 前端技术
客服QQ:1206116161

JavaScript中数据结构与算法(五):经典KMP算法

fgffgfg 于 2018-03-29 10:00:35 创建话题
(27)
(0)
举报

KMP算法和BM算法

KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同

前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右

后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右。

通过上一章显而易见BF算法也是属于前缀的算法,不过就非常霸蛮的逐个匹配的效率自然不用提了O(mn),网上蛋疼的KMP是讲解很多,基本都是走的高大上路线看的你也是一头雾水,我试图用自己的理解用最接地气的方式描述

KMP

KMP也是一种优化版的前缀算法,之所以叫KMP就是Knuth、Morris、Pratt三个人名的缩写,对比下BF那么KMP的算法的优化点就在“每次往后移动的距离”它会动态的调整每次模式串的移动距离,BF是每次都+1,

KMP则不一定

如图BF与KMP前置算法的区别对比

我通过图对比我们发现:

在文本串T中搜索模式串P,在自然匹配第6个字母c的时候发现二等不一致了,那么BF的方法,就是把整个模式串P移动一位,KMP则是移动二位.

BF的匹配方法我们是知道的,但是KMP为什么会移动二位,而不是一位或者三位四位呢?

这就上一张图我们讲解下,模式串P在匹配了ababa的时候都是正确的,当到c的时候才是错误,那么KMP算法的想法是:ababa是正确的匹配完成的信息,我们能不能利用这个信息,不要把"搜索位置"移回已经比较过的位置,继续把它向后移,这样就提高了效率。

那么问题来了, 我怎么知道要移动多少个位置?

这个偏移的算法KMP的作者们就给我们总结好了:

代码如下:

移动位数 = 已匹配的字符数 - 对应的部分匹配值

偏移算法只跟子串有关系,没文本串没毛线关系,所以这里需要特别注意了

那么我们怎么理解子串中已匹配的字符数与对应的部分匹配值?

已匹配的字符:

代码如下:

T : abababaabab
p : ababacb

p中红色的标记就是已经匹配的字符,这个很好理解

部分匹配值:

这个就是核心的算法了,也是比较难于理解的

假如:

代码如下:

T:aaronaabbcc
P:aaronaac

我们可以观察这个文本如果我们在匹配c的时候出错,我们下一个移动的位置就上个的结构来讲,移动到那里最合理?
代码如下:

aaronaabbcc
     aaronaac

那么就是说:在模式文本内部,某一段字符头尾都一样,那么自然过滤的时候可以跳过这一段内容了,这个思路也是合理的

 

知道了这个规律,那么给出来的部分匹配表算法如下:

首先,要了解两个概念:"前缀"和"后缀"。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

"部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度”

我们看看aaronaac的如果是BF匹配的时候划分是这样的

BF的位移: a,aa,aar,aaro,aaron,aarona,aaronaa,aaronaac

那么KMP的划分呢?这里就要引入前缀与后缀了

我们先看看KMP部分匹配表的结果是这样的:

代码如下:

a   a  r  o  n  a  a  c
[0, 1, 0, 0, 0, 1, 2, 0]

肯定是一头雾水,不急我们分解下,前缀与后缀

代码如下:

匹配字符串 :“Aaron”
前缀:A,Aa, Aar ,Aaro
后缀:aron,ron,on,n

移动的位置:其实就是针对每一个已匹配的字符做前缀与后缀的对比是否相等,然后算出共有的长度

部分匹配表的分解

KMP中的匹配表的算法,其中p表示前缀,n表示后缀,r表示结果

代码如下:

a,         p=>0, n=>0  r = 0

aa,        p=>[a],n=>[a] , r = a.length => 1

aar,       p=>[a,aa], n=>[r,ar]  ,r = 0

aaro,      p=>[a,aa,aar], n=>[o,ra,aro] ,r = 0

aaron      p=>[a,aa,aar,aaro], n=>[n,on,ron,aron] ,r = 0

aarona,    p=>[a,aa,aar,aaro,aaron], n=>[a,na,ona,rona,arona] ,r = a.lenght = 1

aaronaa,   p=>[a,aa,aar,aaro,aaron,aarona], n=>[a,aa,naa,onaa,ronaa,aronaa] ,  r = Math.max(a.length,aa.length) = 2

aaronaac   p=>[a,aa,aar,aaro,aaron,aarona], n=>[c,ac,aac,naac,onaac,ronaac]  r = 0

类似BF算法一下,先分解每一次可能匹配的下标的位置先缓存起来,在匹配的时候通过这个《部分匹配表》来定位需要后移动的位数

所以最后aaronaac的匹配表的结果 0,1,0,0,0,1,2,0 就是这么来的

下面将会实现JS版的KMP,有2种

KMP实现(一):缓存匹配表的KMP

KMP实现(二):动态计算next的KMP


KMP实现(一)

匹配表

KMP算法中最重要的就是匹配表,如果不要匹配表那就是BF的实现,加上匹配表就是KMP了

匹配表决定了next下一个位移的计数

针对上面匹配表的规律,我们设计一个kmpGetStrPartMatchValue的方法

function kmpGetStrPartMatchValue(str) {
   var prefix = [];
   var suffix = [];
   var partMatch = [];
   for (var i = 0, j = str.length; i < j; i++) {
    var newStr = str.substring(0, i + 1);
    if (newStr.length == 1) {
     partMatch[i] = 0;
    } else {
     for (var k = 0; k < i; k++) {
      //前缀
      prefix[k] = newStr.slice(0, k + 1);
      //后缀
      suffix[k] = newStr.slice(-k - 1);
      //如果相等就计算大小,并放入结果集中
      if (prefix[k] == suffix[k]) {
       partMatch[i] = prefix[k].length;
      }
     }
     if (!partMatch[i]) {
      partMatch[i] = 0;
     }
    }
   }
   return partMatch;
  }

完全按照KMP中的匹配表的算法的实现,通过str.substring(0, i + 1) 分解a->aa->aar->aaro->aaron->aarona->aaronaa-aaronaac

然后在每一个分解中通过前缀后缀算出共有元素的长度

回退算法

KMP也是前置算法,完全可以把BF那一套搬过来,唯一修改的地方就是BF回溯的时候直接是加1,KMP在回溯的时候我们就通过匹配表算出这个next值即可

//子循环
for (var j = 0; j < searchLength; j++) {
  //如果与主串匹配
  if (searchStr.charAt(j) == sourceStr.charAt(i)) {
    //如果是匹配完成
    if (j == searchLength - 1) {
     result = i - j;
     break;
    } else {
     //如果匹配到了,就继续循环,i++是用来增加主串的下标位
     i++;
    }
  } else {
   //在子串的匹配中i是被叠加了
   if (j > 1 && part[j - 1] > 0) {
    i += (i - j - part[j - 1]);
   } else {
    //移动一位
    i = (i - j)
   }
   break;
  }
}

红色标记的就是KMP的核心点 next的值  = 已匹配的字符数 - 对应的部分匹配值

完整的KMP算法

<!doctype html><div id="test2"><div><script type="text/javascript">
 

  function kmpGetStrPartMatchValue(str) {
   var prefix = [];
   var suffix = [];
   var partMatch = [];
   for (var i = 0, j = str.length; i < j; i++) {
    var newStr = str.substring(0, i + 1);
    if (newStr.length == 1) {
     partMatch[i] = 0;
    } else {
     for (var k = 0; k < i; k++) {
      //取前缀
      prefix[k] = newStr.slice(0, k + 1);
      suffix[k] = newStr.slice(-k - 1);
      if (prefix[k] == suffix[k]) {
       partMatch[i] = prefix[k].length;
      }
     }
     if (!partMatch[i]) {
      partMatch[i] = 0;
     }
    }
   }
   return partMatch;
  }



function KMP(sourceStr, searchStr) {
  //生成匹配表
  var part     = kmpGetStrPartMatchValue(searchStr);
  var sourceLength = sourceStr.length;
  var searchLength = searchStr.length;
  var result;
  var i = 0;
  var j = 0;

  for (; i < sourceStr.length; i++) { //最外层循环,主串

    //子循环
    for (var j = 0; j < searchLength; j++) {
      //如果与主串匹配
      if (searchStr.charAt(j) == sourceStr.charAt(i)) {
        //如果是匹配完成
        if (j == searchLength - 1) {
         result = i - j;
         break;
        } else {
         //如果匹配到了,就继续循环,i++是用来增加主串的下标位
         i++;
        }
      } else {
       //在子串的匹配中i是被叠加了
       if (j > 1 && part[j - 1] > 0) {
        i += (i - j - part[j - 1]);
       } else {
        //移动一位
        i = (i - j)
       }
       break;
      }
    }

    if (result || result == 0) {
     break;
    }
  }


  if (result || result == 0) {
   return result
  } else {
   return -1;
  }
}

 var s = "BBC ABCDAB ABCDABCDABDE";
 var t = "ABCDABD";


 show('indexOf',function() {
  return s.indexOf(t)
 })

 show('KMP',function() {
  return KMP(s,t)
 })

 function show(bf_name,fn) {
  var myDate = +new Date()
  var r = fn();
  var div = document.createElement('div')
  div.innerHTML = bf_name +'算法,搜索位置:' + r + ",耗时" + (+new Date() - myDate) + "ms";
   document.getElementById("test2").appendChild(div);
 }


</script></div></div>

KMP(二)

第一种kmp的算法很明显,是通过缓存查找匹配表也就是常见的空间换时间了。那么另一种就是时时查找的算法,通过传递一个具体的完成字符串,算出这个匹配值出来,原理都一样

生成缓存表的时候是整体全部算出来的,我们现在等于只要挑其中的一条就可以了,那么只要算法定位到当然的匹配即可

next算法

function next(str) {
  var prefix = [];
  var suffix = [];
  var partMatch;
  var i = str.length
  var newStr = str.substring(0, i + 1);
  for (var k = 0; k < i; k++) {
   //取前缀
   prefix[k] = newStr.slice(0, k + 1);
   suffix[k] = newStr.slice(-k - 1);
   if (prefix[k] == suffix[k]) {
    partMatch = prefix[k].length;
   }
  }
  if (!partMatch) {
   partMatch = 0;
  }
  return partMatch;
}

其实跟匹配表是一样的,去掉了循环直接定位到当前已成功匹配的串了

完整的KMP.next算法

<!doctype html><div id="testnext"><div><script type="text/javascript">
 
  function next(str) {
    var prefix = [];
    var suffix = [];
    var partMatch;
    var i = str.length
    var newStr = str.substring(0, i + 1);
    for (var k = 0; k < i; k++) {
     //取前缀
     prefix[k] = newStr.slice(0, k + 1);
     suffix[k] = newStr.slice(-k - 1);
     if (prefix[k] == suffix[k]) {
      partMatch = prefix[k].length;
     }
    }
    if (!partMatch) {
     partMatch = 0;
    }
    return partMatch;
  }

  function KMP(sourceStr, searchStr) {
    var sourceLength = sourceStr.length;
    var searchLength = searchStr.length;
    var result;
    var i = 0;
    var j = 0;

    for (; i < sourceStr.length; i++) { //最外层循环,主串

      //子循环
      for (var j = 0; j < searchLength; j++) {
        //如果与主串匹配
        if (searchStr.charAt(j) == sourceStr.charAt(i)) {
          //如果是匹配完成
          if (j == searchLength - 1) {
           result = i - j;
           break;
          } else {
           //如果匹配到了,就继续循环,i++是用来增加主串的下标位
           i++;
          }
        } else {
         if (j > 1) {
          i += i - next(searchStr.slice(0,j));
         } else {
          //移动一位
          i = (i - j)
         }
         break;
        }
      }

      if (result || result == 0) {
       break;
      }
    }


    if (result || result == 0) {
     return result
    } else {
     return -1;
    }
  }

 var s = "BBC ABCDAB ABCDABCDABDE";
 var t = "ABCDAB";


  show('indexOf',function() {
   return s.indexOf(t)
  })

  show('KMP.next',function() {
   return KMP(s,t)
  })

  function show(bf_name,fn) {
   var myDate = +new Date()
   var r = fn();
   var div = document.createElement('div')
   div.innerHTML = bf_name +'算法,搜索位置:' + r + ",耗时" + (+new Date() - myDate) + "ms";
    document.getElementById("testnext").appendChild(div);
  }

</script></div></div>

git代码下载: https://github.com/JsAaron/data_structure

扫码关注TE官方微博 扫码关注TE官方微博
解读absolute与relative python实现验证码识别功能 WPF实现带全选复选框的列表控件 一个可以兼容IE FF的加为首页与加入收藏实现代码 jquery判断RadioButtonList和RadioButton中是否有选中项示例 探究Python的Tornado框架对子域名和泛域名的支持 SQLSERVER服务手工启动 批处理文件 python 调用HBase的简单实例 DedeCMS图集中缩略图不显示的解决方法 MySQL timestamp的类型与时区实例详解 苹果mac怎么使Mission Control窗口按应用程序成组? 深入浅析search 搜索框的写法 Nodejs回调加超时限制两种实现方法 JavaScript实现的链表数据结构实例 jquery实现最简单的滑动菜单效果代码 Python实现脚本锁功能(同时只能执行一个脚本) DEDECMS转移data目录后 验证码不显示解决办法 在C#中生成与PHP一样的MD5 Hash Code的方法 Bootstrap 粘页脚效果 简单介绍PHP的责任链编程模式 jQuery接受后台传递的List的实例详解 css 背景样式属性说明 linux su命令参数及用法详解(linux切换用户命令) Linux系统中查看硬件信息与运行状态的方法总结 php环境无法上传文件的解决方法 dedecms的sql标签中传入参数的方法 ASP 微信公共平台接口实现代码 JavaScript 一道字符串分解的题目 javascript 判断一个对象为数组的方法 JavaScript中reduce()方法的使用详解 批量下载对路网图片并生成html的实现方法 不同的jQuery API来处理不同的浏览器事件 使用bootstrap-paginator.js 分页来进行ajax 异步分页请求示例 上传文件返回的json数据会被提示下载问题解决方案 jQuery.parseHTML() 函数详解 分别用marquee和div+js实现首尾相连循环滚动效果,仅3行代码 springboot集成schedule实现定时任务 Android Studio 合并module到统一文件夹的方法 基于wxpython开发的简单gui计算器实例 php下FCKeditor2.6.5网页编辑器的使用方法 电脑蓝屏的紧急处理办法的详细描述 Node.js的基本知识简单汇总 每天一个linux命令 head命令 javascript模拟实现C# String.format函数功能代码 javascript数组操作方法小结和3个属性详细介绍 VS2015使用scanf报错的解决方法 巧用CSS的MASK滤镜 解决中文版Chrome下网页不能显示小于12px字体 js父页面与子页面不同时显示的方法 JavaScript高级程序设计 阅读笔记(十七) js事件 js中string转int把String类型转化成int类型 Docker的集成部署攻略 javascript 函数调用的对象和方法 解析在PHP中使用全局变量的几种方法 PowerShell编程中的一些命名规则参考 IOS获取当前版本号 Bundle ID等信息的方法详解 关于query Javascript CSS Selector engine BootStrap表单控件之文本域textarea NodeJs中的VM模块详解 Powershell小技巧之轻松从网上下载文件 Python三级菜单的实例 ubuntu12.04安装tftp、配置tftp服务错误的解决方法 用tensorflow实现弹性网络回归算法 windows服务器指定IP地址才能进行远程访问桌面设置方法 深入了解iOS开发中UIWindow的相关使用 Vuejs第十篇之vuejs父子组件通信 jQuery实现tab标签自动切换的方法 js与jquery正则验证电子邮箱、手机号、邮政编码的方法 CSS+Jquery实现页面圆角框方法大全 Android使用OkHttp进行网络同步异步操作 jquery实现侧边栏左右伸缩效果的示例 Es6 写的文件import 起来解决方案详解 在Ubuntu 16.04中创建GIF动图的方法 一种Javascript解释ajax返回的json的好方法(推荐) vue template中slot-scope_scope的使用方法 MongoDB安全配置详解 JS二分查找算法详解 使用Python操作MySQL的一些基本方法 python使用PyCharm进行远程开发和调试 AngularJS 让人爱不释手的八种功能 JSP中一些JSTL核心标签用法总结 JavaScript中使用数组方法汇总 一句话 asp木马加密版 彻底突破杀毒软件 windows下安装mongodb以及node.js连接mongodb实例 javascript实时显示北京时间的方法 javascript时间戳和日期字符串相互转换代码(超简单) 通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法 macos 10.14有哪些新功能 12项苹果macos 10.14新特性汇总 浅析JavaScript动画 linux中cp 命令使用介绍(复制文件或者目录) PHP中执行MYSQL事务解决数据写入不完整等情况 jquery+ajax实现跨域请求的方法 详谈表单格式化插件jquery.serializeJSON jQuery针对input的class属性写了多个值情况下的选择方法 解决python3 urllib 链接中有中文的问题 SEO网站跳出率、PV值达到多少才算及格 Yii框架分页实现方法详解 ecshop图文安装过程详解 Python 自动安装 Rising 杀毒软件 Android实现搜索本地音乐的方法 JS中BOM相关知识点总结(必看篇) ASP.NET Core使用微软官方类库实现汉字转拼音 JS库之Waypoints的用法详解 HTML表格标记教程(23) 行的暗边框色属性BORDERCOLORDARK 深入了解javascript中的prototype与继承 javascript实现日期时间动态显示示例代码 jquery 学习之二 属性相关 jquery中$.fn和图片滚动效果实现的必备知识总结 Function.prototype.apply()与Function.prototype.call()小结 在ubuntu中安装32位、64位chrome的方法 jQuery插件FusionCharts绘制2D柱状图和折线图的组合图效果示例【附demo源码】 lixux系统中bash命令下一些操作技巧 学会后可事半功倍 jQuery匹配文档链接并添加class的方法 PHP array_multisort() 函数的深入解析 make arm-linux- conmand not found错误处理探讨 纯JS实现简单的日历 jQuery中 visible选择器用法实例 js对象基础实例分析 mssql 存储过程调用C#编写的DLL文件 Javascript创建自定义对象 创建Object实例添加属性和方法 jQuery Masonry瀑布流插件使用详解 苹果Mac系统锁屏不待机效果设置方法介绍 Python3.5编程实现修改IIS WEB.CONFIG的方法示例 IIS的FastCGI漏洞处理方法 Ruby设计模式编程中对外观模式的应用实例分析 JS实现网页Div层Clone拖拽效果 你所不了解的javascript操作DOM的细节知识点(一) python从ftp下载数据保存实例 Python使用defaultdict读取文件各列的方法 Linux Shell脚本系列教程(二):终端打印命令详解 苹果macOS Sierra beta2开发者预览版固件上手视频 Apple Watch自动解锁 Lua教程(二十二):userdata javascript多行字符串的简单实现方式 原生js开发的日历插件 jQuery实现每隔一段时间自动更换样式的方法分析 .NET中的IO操作之文件流用法分析 Python内置函数的用法实例教程 jquery中post方法用法实例 微信小程序 密码输入(源码下载) Python映射拆分操作符用法实例 递归实现两个二叉树的比较 js html5 css俄罗斯方块游戏再现 jsp连接数据库大全 ES6 系列之 WeakMap的使用示例 jQuery Easyui Treegrid实现显示checkbox功能 JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变 如何处理ASP.NET Core中HTML5客户端路由回退的问题 Android开发使用json实现服务器与客户端数据的交互功能示例 SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它 jquery 追加元素append、prepend、before、after用法与区别分析 swift 3.0中realm封装类示例代码 javascript禁止超链接跳转的方法 JavaScript实现DIV层拖动及动态增加新层的方法 基于Jquery实现仿百度百科右侧导航代码附源码下载 Android圆角按钮的制作方法 PHP利用Cookie设置用户30分钟未操作自动退出功能 CSS包含中文的问题说明 js 打开新页面在屏幕中间的实现方法 ASP固定比例裁剪缩略图的方法 BootstrapValidator不触发校验的实现代码 JavaScript 浮动定位提示效果实现代码第1_2页 MariaDB(MySQL)创建、删除、选择及数据类型使用详解 ASP 快速执行动态网页 centos配置ssh免密码登录后仍要输入密码的解决方法 原生javascript实现解析XML文档与字符串 Python设计模式之抽象工厂模式 asp中向文本框输出数据原样式的函数 JavaScript参数个数可变的函数举例说明 Windows下的Jupyter Notebook 安装与自定义启动(图文详解) 如何使用JSP访问MySQL数据库 写一段简单的PHP建立文件夹代码 asp.net 2.0里也可以用JSON的使用方法 Apache 2.0.55 for Linux 下载 jquery获取当前日期的方法 JavaScript中ES6字符串扩展方法 Python 处理数据的实例详解 Centos 升级到python3后pip 无法使用的解决方法 js调用css属性写法 Asp.Net 无刷新文件上传并显示进度条的实现方法及思路 15个Linux Grep命令使用实例(实用、常用) ASP让url的中文显示为编码 基于JavaScript实现购物车功能 简介JavaScript中charAt()方法的使用 ubuntu 12.04 安装deb包出现内部错误解决办法 JavaScript实现弹出模态窗体并接受传值的方法 CSS常用属性的默认值详细整理 php方法调用模式与函数调用模式简例 spring boot使用properties定义短信模板的方法教程 基于JQuery的抓取博客园首页RSS的代码 对python 矩阵转置transpose的实例讲解 thinkPHP5.0框架安装教程 JS实现百度搜索接口及链接功能实例代码 thinkphp多层MVC用法分析 php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比 PHP实现的交通银行网银在线支付接口ECSHOP插件和使用例子 学习python的几条建议分享 SQLServer存储过程中事务的使用方法 php处理json格式数据经典案例总结 javascript用正则表达式把1234567890替换为abcdefghij 网页下载文件期间如何防止用户对网页进行其他操作
纯CSS3滑动开关按钮特效.zip 金色企业CSS网页模板.zip CSS3实现3D折叠字体效果代码.zip html5手机触屏左右滑动切换特效.zip jQuery select下拉菜单.zip wordpress经典大气企业主题.zip Canvas光束光线爆炸特效.zip 带放大效果jquery左右滚动图片代码.zip 微信小程序源码-蓝果小镇商城 android 中多任务断点续传下载 【32赞HTML5响应式系列之小情绪风格】仿Epsilon Elements触屏版html5响应式手机wap网站模板.zip js键盘控制6键弹钢琴特效.zip 【PHP源码】MvMmall 网店系统 v5.5.1 Bulid 090505_mvmmall5.zip RSA加密算法BASE64,加密解密验签,Java实现Demo CSS3实现会眨眼的蚱蜢动画.zip jquery顶部固定导航下拉菜单.zip 【ASP.NET源码】黄金顶王 V1.2_kingvote12.zip jquery电影相册图片预览.zip jQuery 3D响应式菜单导航特效.zip jQuery实用的注册表单验证代码.zip jQuery圆形箭头焦点图.zip 微信小程序源码-明星图(含NODEJS后端) spring boot多数据源自动路由 Android socket通讯的长连接 CSS3时钟圆形立体倒计时代码.zip 网络世界html5网站模版.zip fregment的快速使用框架 前端设计作品展示HTML5模板.zip easyui经典后台项目管理系统框架模板源代码下载 css3唱片滑动效果.zip jQuery顶部定位导航.zip jQuery左右切换焦点轮播幻灯片.zip jQuery图片动态旋转插件.zip 【PHP源码】GAODO网络商城购物系统_kgogomall.zip jQuery触摸友好滑块插件Glide.zip jQuery缓慢弹出下拉tab导航.zip jQuery中国省市区三级联动特效.zip jQuery带评论的星星评分代码.zip 单页固定导航html模板.zip jQuery手机端Lightbox图片展示.zip Java图形化界面实现图书管理系统 基于jQuery+CSS3样本书特效.zip jQuery跑马灯支持任何DOM元素.zip jQuery用户自定义日程表管理代码.zip 爱淘客网站源码授权版(淘宝专业导购网站).zip 绿色小清新宽屏bootstrap模板.zip 运动鞋网上销售HTML模板.zip CSS3悬挂的照片墙效果代码.zip CSS3实现蟠桃树蟠桃摇晃动画特效.zip jQuery自动补全筛选input代码.zip JSP超市进销存管理系统 jQuery天空流星雨动画特效.zip 客车制造企业网站模板.zip jquery动态弹性多级下拉菜单.zip jquery仿windows计算器.zip jQuery可放大任何HTML元素放大镜.zip Discuz! x2.5质感灰白色模板.zip PHPWind论坛 哈猫风格.zip java 连接 FTP 文件操作(上传,下载,删除,复制 jQuery可快进拖动切换幻灯片sampSlider.zip jQuery右侧悬浮楼层滚动代码.zip jquery配合seajs框架实现返回顶部特效.zip 微信小程序源码-装修预约小程序 浅蓝色风格医疗行业模板.zip wordpress黄色修边主题.zip loading页面加载图标css3代码.zip HTML5炫酷明星专辑网页模板.zip jquery hover图片滑动.zip jQuery网站评论文本框表情选择.zip jquery图片滑动翻牌效果.zip JSP旅游网站建设设计与实现(源代码+论文) jQuery过渡幻灯片切换.zip ZOL五屏焦点图广告代码.zip jquery带二维码的在线客服.zip jQuery鼠标滚动垂直全屏切换代码.zip 支付宝RSA加密签名验签工具 搜狗浏览器7.0页面特效下载.zip 女性时尚门户网站模板.zip Spring3.0+Hibernate4.0+SpringMVC整合ExtJS4 jQuery鼠标点击下拉显示信息代码.zip Wordpress 青色自然.zip SVG+CSS3实现弹性跳动动画特效.zip 【PHP源码】PHP小新闻系统_yd631_php_news.zip 视差滚动parallax插件.zip 【PHP源码】magento开源电子商务平台 v1.3.2.1 多国语言版_magento.zip jquery多功能响应式相册插件Strip.zip 微信小程序源码-车源宝寻车广场 纸一样展开jQuery特效.zip 微信小程序源码-酒商推广 jQuery可控制雪碧图sprites插件.zip owl-carousel人物信息展示特效.zip css3安卓3D时钟翻转.zip 视差滚动房地产网站模板.zip 凡客诚品wordpress主题.zip jQuery表单元素动态增加删除代码.zip html购物网站模板下载.zip jQuery相册图片滤镜效果.zip CSS3实现Android4.4加载动画.zip 国外商务联系公司网页模板.zip jQuery实现渐现渐隐弹出层.zip jquery地图特效全国网点查看代码.zip 网上书店系统源码(JSP+sql数据库)下载 炫舞DJ音乐css模板下载.zip jQuery带结束播放音乐的定时器代码.zip jQuery仿百度新闻首页焦点图.zip 咪咕音乐官网jQuery焦点图.zip 个性的个人相册html5模板.zip jQuery瀑布流插件Grid-A-Licious.zip HTML5+CSS3酷炫搜索框特效.zip jquery焦点图轮播插件excoloSlider.zip 3D旋转效果幻灯片.zip 游泳馆企业网站模板.zip 【PHP源码】php硬盘资源管理器_php_driver_manage.zip mybatis 由浅入深全套视频教程 SSM 整合框架 纯净 产品介绍单页网页模板.zip jQuery全屏背景滑块幻灯片.zip jQuery全年日历工作考勤表代码.zip 图片集鼠标悬停CSS3过渡效果.zip 创意美食摄影单页模板下载.zip 资源站设计CSS模板下载.zip jQuery带聚焦效果图片切换代码.zip jQuery加入购物车飞入动画特效.zip jQuery手机触屏滑动切换幻灯片.zip 带缩略图jQuery幻灯片相册代码.zip 上古世纪jQ焦点图.zip 宠物狗乐园html模板.zip 超大幻灯片css宽屏模板.zip 人力资源管理系统项目源码 (Struts+Hibernate) Simpli Flat蓝色管理模板.zip jQuery垂直Tabs新闻滑块.zip jquery鼠标移到图片显示半透明文字层.zip HTML5音频可视化频谱跳动代码.zip jQuery滑动加载进度条代码.zip css3 input按钮样式代码.zip CSS3动画悬停显示文字特效.zip jQuery网页定时提醒闹钟.zip javaExcel大数据导出 jQuery动态添加删除编辑标签代码.zip 背景Canvas 3D线条动画特效.zip jQuery滚动菜单插件Section Menu.zip jQuery随机抽中手机号码抽奖代码.zip 纯CSS3实现旺仔头像动画特效.zip 【PHP源码】圣者文章管理系统 SWCms 3.0.2 开源版_swcms3.zip css3实现多款创意按钮.zip 仿QQ空间可拉伸头部 jQuery+CSS3流畅下拉菜单特效.zip 【PHP源码】网猫影视系统 NetMao 5.2.0 SC GBK 正式版_netmao_sc_gbk.zip 高校图书馆个性化推荐系统 spring+springmvc+mybatis+bootstrap整合案例 JAVA物流管理系统开发 CSS3图像过滤移轴效果.zip jQuery .prop()属性全选反选 AJAX Photo Gallery.zip jQuery按钮点击loading加载.zip jquery鼠标滑动图片移位.zip jQuery商城淡入淡出焦点图.zip Android基于SurFaceView的小游戏 HUD科幻数据屏幕动画界面特效.zip 框架首页easyui,bootstrap例子展示。 jQuery幻灯片滑动插件Blueberry.zip 多图多屏jQuery幻灯片代码.zip html5手机登录表单验证代码.zip css3网页加载动画图标下载.zip 【PHP源码】PHP留言程序源代码版[BBWPS] V2.1_bbwps_guestbook.zip 大气红色商务网页模板.zip 可下拉的PinnedHeaderExpandableListView的实现 微信小程序源码-微电商商城 可暂定滚动的TAB标签代码.zip 黑色虚拟主机商网站模板.zip Flash+XML前后按钮超酷焦点图.zip jQuery+HTML5实现滑块特效下载.zip jquery贪吃蛇游戏特效代码.zip apktool 反编译工具 JS确认框和对话框插件下载.zip JSP自动排课管理系统(源代码+论文+开题报告) 几十套精典H5页面模板,各个行业 蓝色大屏客户服务网站模板.zip 带留言功能的在线客服代码.zip jquery实现html5图片上传.zip jquery经典Lightbox弹出框特效.zip js悬浮在右侧橘黄色在线客服.zip mootools实现checkbox和radiobox效果.zip 青春活力健身网站模板.zip PSD分层婚纱模板下载.zip 蓝色大气制造业网站模板.zip 蔬菜品种企业官方模板.zip 织梦dedecms手机wap插件同数据库手机网站.zip CSS3鼠标经过立体翻转切换特效.zip 旅行酒店宾馆整站模板下载.zip 蓝色外国语教育网站模板.zip 三栏布局自适应wordpress主题.zip wordpress时间轴Scopic主题.zip jQuery图片自适应全屏幻灯片.zip 拳击健身会所网站模板.zip 汽车维修服务公司网站模板.zip 微信小程序源码-集思笑话,含Vue.js后端,点赞 产品展示html5网站模板.zip jquery可播放视频的焦点图.zip DiscuzX2.5蓝色经典风格模板.zip
举报X