KMP算法总结
2016-05-29 16:06
459 查看
本文参考:字符串匹配的KMP算法
KMP算法是一个效率很高的字符串匹配算法,时间复杂度能做到O(n)级别。在这里整理记录该内容。
现在,为了理解这个算法,首先给出一个实例,来感受一下它的匹配过程。
一个例子
举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"?
1、首先,比较"BBC ABCDAB ABCDABCDABDE"和"ABCDABD"的首个字符,’B’和’A’不同,搜索词向后移动一位。
2、’B’和’A’不同,搜索词向后移动一位。就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。
3、接着比较搜索词与参考词的下一个字符。
4、这时,出现了最后一个字母不匹配的情况,如何移动字符串使其,能够快速并不重复比较已经比较过的部分能。KMP算法就是解决这一问题的。
5、KMP算法借助一张“部分匹配表”解决重复比较的问题。搜索词生成的“部分匹配表”如下:
这张表如何使用呢?首先,假设我们比较左侧’B’时,发现不相等,那么将参考字符串中的词跟搜索词0号位置的字符’A’比较;同理,比较搜索词末尾单词时,发现不等,那么就将参考字符串中的词跟搜索词2号位置的字符’C’比较;当搜索词的0号位置的‘A’跟参考字符串比较不相等时,就将‘A’与参考字符串的下一个位置的字符串进行比较。
6、有了部分参考表,继续步骤4的操作,得到如下,依然不相等,则让搜索词中2号位置的字符与空格比较。
7、同样不相等,则将参考词的0号位置的字符与参考串的空格字符的下一个字符比较。
8、到这一步依次比较每个字符,发现最后一个字符不等,则继续比较搜索词的2号位置的字符相等。
9、最后比较的到了,比较成功了,参考字符串中含有搜索词。
“部分匹配表”是什么原理
这里引入了“前缀”和“后缀”的概念。要求“前缀”的第一字符不在“后缀”中,同样“后缀”的最后一个字符不能在“前缀”中。举例说明,针对搜索词,“前缀”有:"A"、"AB"、"ABC"、"ABCD"、"ABCDA"、"ABCDAB";“后缀”有:"BCDABD"、"CDABD"、
"DABD"、"ABD"、" BD"、"D"。有了这两个概念后,下面继续……
“部分匹配表”表示不包括当前字符的情况下,前面字符组成的字符串的前缀和后缀共有的元素最长长度。
根据下表,针对每个元素,分析每个值的由来:
匹配表0位置:默认为-1
匹配表1位置:因为”A”前面没有“前缀”和“后缀”,所以为0
匹配表2位置:”AB” “前缀”为”A”,“后缀”为”B”。公共长度为0
匹配表3位置:”ABC” “前缀”和“后缀”无公共部分。公共长度为0
匹配表4位置:”ABCD” “前缀”和“后缀”无公共部分。公共长度为0
匹配表5位置:”ABCDA” “前缀”和“后缀”有公共部分”A”。公共长度为1
匹配表6位置:”ABCDAB” “前缀”和“后缀”有公共部分”AB”。公共长度为2
KMP算法是一个效率很高的字符串匹配算法,时间复杂度能做到O(n)级别。在这里整理记录该内容。
现在,为了理解这个算法,首先给出一个实例,来感受一下它的匹配过程。
一个例子
举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"?
1、首先,比较"BBC ABCDAB ABCDABCDABDE"和"ABCDABD"的首个字符,’B’和’A’不同,搜索词向后移动一位。
2、’B’和’A’不同,搜索词向后移动一位。就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。
3、接着比较搜索词与参考词的下一个字符。
4、这时,出现了最后一个字母不匹配的情况,如何移动字符串使其,能够快速并不重复比较已经比较过的部分能。KMP算法就是解决这一问题的。
5、KMP算法借助一张“部分匹配表”解决重复比较的问题。搜索词生成的“部分匹配表”如下:
这张表如何使用呢?首先,假设我们比较左侧’B’时,发现不相等,那么将参考字符串中的词跟搜索词0号位置的字符’A’比较;同理,比较搜索词末尾单词时,发现不等,那么就将参考字符串中的词跟搜索词2号位置的字符’C’比较;当搜索词的0号位置的‘A’跟参考字符串比较不相等时,就将‘A’与参考字符串的下一个位置的字符串进行比较。
6、有了部分参考表,继续步骤4的操作,得到如下,依然不相等,则让搜索词中2号位置的字符与空格比较。
7、同样不相等,则将参考词的0号位置的字符与参考串的空格字符的下一个字符比较。
8、到这一步依次比较每个字符,发现最后一个字符不等,则继续比较搜索词的2号位置的字符相等。
9、最后比较的到了,比较成功了,参考字符串中含有搜索词。
“部分匹配表”是什么原理
这里引入了“前缀”和“后缀”的概念。要求“前缀”的第一字符不在“后缀”中,同样“后缀”的最后一个字符不能在“前缀”中。举例说明,针对搜索词,“前缀”有:"A"、"AB"、"ABC"、"ABCD"、"ABCDA"、"ABCDAB";“后缀”有:"BCDABD"、"CDABD"、
"DABD"、"ABD"、" BD"、"D"。有了这两个概念后,下面继续……
“部分匹配表”表示不包括当前字符的情况下,前面字符组成的字符串的前缀和后缀共有的元素最长长度。
根据下表,针对每个元素,分析每个值的由来:
匹配表0位置:默认为-1
匹配表1位置:因为”A”前面没有“前缀”和“后缀”,所以为0
匹配表2位置:”AB” “前缀”为”A”,“后缀”为”B”。公共长度为0
匹配表3位置:”ABC” “前缀”和“后缀”无公共部分。公共长度为0
匹配表4位置:”ABCD” “前缀”和“后缀”无公共部分。公共长度为0
匹配表5位置:”ABCDA” “前缀”和“后缀”有公共部分”A”。公共长度为1
匹配表6位置:”ABCDAB” “前缀”和“后缀”有公共部分”AB”。公共长度为2
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树