KMP算法是字符串匹配的经典算法,简称 看毛片, 理论知识请直接看阮一峰老师的这篇文章,我看完文章之后尝试对算法进行了实现。

一句话总结KMP算法的核心思想:就是跳过已经对比的部分

而KMP算法的核心组成就是部分匹配表 + 回退算法

部分匹配表1.0版本

            function KMPpartMatchTable(str) {
var matchTable = [0];
var prefix = [],
suffix = [];
for(var i = 1; i < str.length; i++) {
prefix = getPrefix(str.substr(0, i + 1))
suffix = getSuffix(str.substr(0, i + 1)) var ret = [0]; //默认设置一个0,防止-Infinity
//对比2个数组,是否有重复的
prefix.forEach(function(n, i) {
for(var j = i; j < suffix.length; j++) {
if(n == suffix[j]) {
ret.push(n.length)
}
}
})
matchTable.push(Math.max.apply(null, ret))
}
//生成前缀数组
function getPrefix(s) {
let ret = []
for(var len = s.length; len > 0; len--) {
if(len == s.length) continue;
ret.push(s.substring(0, len))
}
return ret.reverse();
}
//生成后缀数组
function getSuffix(s) {
let ret = []
for(var len = s.length; len > 0; len--) {
if(len == s.length) continue;
ret.push(s.substring(len, s.length))
}
return ret.reverse();
}
return matchTable
}

这是我第一版写出来的,可以看到2个getPrefix和getSuffix有大部分是重复的代码。方便理解。需要for循环2次字符串,但不利于性能。所以可以将他们进行精简合并为1次

部分匹配表2.0版本

            function KMPpartMatchTable(str) {
var matchTable = [0];
var prefix = [],
suffix = [];
for(var i = 1; i < str.length; i++) {
// prefix = getPrefix(str.substr(0, i + 1))
// suffix = getSuffix(str.substr(0, i + 1))
var s = str.substr(0, i + 1);
for(var len = s.length; len > 0; len--) {
if(len == s.length) continue;
prefix.push(s.substring(0, len)) //前缀数组
suffix.push(s.substring(len, s.length)) //后缀数组
} var ret = [0]; //默认设置一个0,防止-Infinity
//对比2个数组,是否有重复的
prefix.forEach(function(n, i) {
for(var j = i; j < suffix.length; j++) {
if(n == suffix[j]) {
ret.push(n.length)
}
}
})
matchTable.push(Math.max.apply(null, ret))
}
return matchTable
}
            KMPpartMatchTable('ABCDABD')//[0,0,0,0,1,2,0]
 

改进过后,逻辑没那么直观了。但一次字符串for循环就生成出了前缀和后缀数组

回退算法

            function KMP(sourceStr, targetStr) {
var partMatchValue = KMPpartMatchTable(targetStr); //拿到匹配表
var result = false;
for(var i = 0; i < sourceStr.length; i++) {
for(var k = 0; k < targetStr.length; k++) {
if(str.charAt(k) == sourceStr.charAt(i)) {
if(k == targetStr.length - 1) {
result = true;
break;
} else {
i++;
}
} else {
if(k > 0 && partMatchValue[k - 1] > 0) {
k = partMatchValue[k - 1] - 1;
} else {
break;
}
}
}
if(result) {
break;
}
}
return result
} var ss = 'ABCDAB ABCDAB ABCDAABCABCDABDABCDABDDABDBD'
var str = 'ABCDABD'
console.log(KMP(ss, str)) //true

KMP算法用JavaScript实现的更多相关文章

  1. 数据结构与算法JavaScript (五) 串(经典KMP算法)

    KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...

  2. KMP算法——Javascript实现

    腾讯和阿里的笔试刚过去了,里面有很多题都很值得玩味的.之前Blog积累的很多东西,还要平时看的书,都有很大的帮助.这个深有体会啊! 例如,腾讯有一道算法题是吃香蕉(好邪恶的赶脚..),一次吃一根或者两 ...

  3. javascript实现KMP算法(没啥实用价值,只供学习)

    简单粗暴上代码 KMP的原理我就不讲了,想转过弯儿来不容易,建议大家先学会了怎么推导出next数组规律,然后准备两张纸,大纸上写上一行你要匹配的目标字符串,并分别写出位置编号,小纸上写上一行,也写上位 ...

  4. 理解 KMP 算法

    KMP(The Knuth-Morris-Pratt Algorithm)算法用于字符串匹配,从字符串中找出给定的子字符串.但它并不是很好理解和掌握.而理解它概念中的部分匹配表,是理解 KMP 算法的 ...

  5. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  6. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  7. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  8. KMP算法实现

    链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...

  9. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

随机推荐

  1. Unity之使用技巧记录

    A:写了个死循环Unity无响应崩溃了怎么办? Q::到文件夹里找到刚刚写的脚本,把错误的代码屏蔽掉,再回到Unity

  2. BootStrap-select 插件的使用

    这是一款下拉框多选的插件,非常的抢到,什么样式都是有的:首先去参看一下官网的信息,详细介绍是怎么使用的: 相关官网网址:  https://silviomoreto.github.io/bootstr ...

  3. Element ui 中使用table组件实现分页记忆选中

    我们再用vue和element-ui,或者其他的表格的时候,可能需要能记忆翻页勾选,那么实现以下几个方法就ok了 示例如下 <el-table :data="tableData&quo ...

  4. Algorithm——两个排序数组的中位数

    ps:城际的网速还是不错的-

  5. css动画和jq动画的简单区分

    有很多不怎么用css3写动画的同学经常会对其中css3的transform,transition,translate,animation,@keyframes等等动画属性混淆错乱,经常使用了发现没有效 ...

  6. ComboBox Style

    <SolidColorBrush x:Key="ComboBoxNormalBorderBrush" Color="#e3e9ef" /> < ...

  7. ew代理实战

    前言 渗透内网代理必不可少,本文做个记录 正文 工具下载地址 http://rootkiter.com/EarthWorm/ ssocksd开启 socks5 代理 环境 代理:192.168.211 ...

  8. shiro web 集成

    集成方法 shiro与web集成,主要是通过配置一个ShiroFilter拦截所有URL,其中ShiroFilter类似于SpringMVC的前端控制器,是所有请求入口点,负责根据配置(如ini配置文 ...

  9. svn 同步资源库时忽略某些文件类型和文件夹

    项目开发中,开发人员经常用SVN来管理代码,在和服务器同步时,每次都看到一堆.class,.log,target等文件,这样很不舒服. 解决方法: 打开:window-->preferences ...

  10. 通过Places API Web Service获取兴趣点数据

    实验将爬取新加坡地区的银行POI数据 数据库采用mongodb,请自行安装,同时申请google的key 直接上代码 #coding=utf-8 import urllib import json i ...