字符串匹配KMP
本文内容学习自字符串匹配的KMP算法
如果有一个字符串BBC ABCDAB ABCDABCDABDE
,要查找里面是否有搜索串 ABCDABD
。
那实现代码最简单的方法就是 两层循环
,以此比较。
文章图片
字符串比较步骤
- 1 字符串的第一位和搜索串的第一位不同,搜索串后移一位,继续比较
- 2 字符串的第一位和搜索串的第一位相同,比较字符串的第二位和搜索串的第二位是否相同。直到全部相同,查找结束。否则搜索串后移一位,继续比较
KMP
kmp 算法的优点就是简化了比较的次数,不用
逐步比较
字符串比较步骤
- 1 字符串的第一位和搜索串的第一位不同,搜索串后移一位,继续比较 (
与上面相同
) - 2 字符串的第一位和搜索串的第一位相同,比较字符串的第二位和搜索串的第二位是否相同。直到全部相同,查找结束。否则搜索串后移(
这里做了优化
),继续比较
文章图片
字符串的第一位和搜索串的第一位不同,搜索串后移一位 继续比较。。。 直到
文章图片
这里已经有六位相同
- 这里已经有六位数是相同的了,如果按照普通的比较,只能后移一位重新比较
- 这里 kmp 算法会借助已匹配的这一位计算后移的
位数
文章图片
对已匹配的字符串计算步骤 按照一般方法是这样比较的
文章图片
kmp 位移数会计算移动步数
我们的目的是找到搜索串全匹配的位置,可以这样优化位移数
-
字符串
已经有6个字符串与搜索串
中的6个字符串相同,只要关心搜索串
中已匹配的6个字符串即可- 假设
搜索串
中已匹配的6个字符串全不相同,就可以移动全部的相同字符串
文章图片
- 如果
搜索串
中已匹配的6个字符串有相同的,就可以移动部分字符串
- 假设
文章图片
因此:
位移数 = 已匹配的长度 - 元素中重复出现的长度步骤图如下
文章图片
步骤图.png 匹配数代码实现 建立搜索串 对应长度中的重复字符串
let startTimestamp=new Date().getTime()
let string = 'BBC ABCDAB ABCDABCDABDE'
let keyString = 'ABCDABD'
let arr = []
// 建立搜索关键字数组
let findRelation = function() {
let searchArr = []
let relationArr = []
for (let i = 0;
i < keyString.length;
i++) {
searchArr.push(keyString.slice(0, i+1))
}
for (let i = 0;
i < searchArr.length;
i++) {
let sameFlag = 0 // 共有长度计数
if (searchArr[i].length === 1) { // 字符串长度为1时,共有长度为0
relationArr.push({goal: searchArr[i], sameFlag: sameFlag})
}else {
let string =searchArr[i]
let frontArr = []
let backArr = []
// 处理正反两个数组,并且比较,获取共有数据长度
for (let i = 0;
i < string.length-1;
i++) {
frontArr.push(string.slice(0, i+1))
backArr.push(string.slice(-(i+1)))
}
for (let i = 0;
i < frontArr.length;
i++) {
if(frontArr[i] === backArr[i]) {
sameFlag = backArr[i].length
}
}
relationArr.push({goal: searchArr[i], sameFlag: sameFlag})
}
}
return relationArr
}
文章图片
匹配数.png 建立匹配数后,就可以进行循环比较了
KMP 代码
Document - 锐客网
【字符串匹配KMP】ps: 关于 KMP 应该还有优化方法
未匹配的字符串和
搜索串
中的没有相同的。
- 此时可以移动整个字符串的位置
文章图片
推荐阅读
- 一起来学习C语言的字符串转换函数
- opencv|opencv C++模板匹配的简单实现
- 字符串拼接成段落,换行符(\n)如何只执行n-1次
- C语言的版本比较
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- JS截取字符串的方法详解
- Python|Python 字符串 子串 回文串
- 正则匹配
- LeetCode|LeetCode 每日一题 [52] 表示数值的字符串
- Swift|Swift 字符串转数组