
KMP模式匹配算法
初始化: 创建一个长度为t.length()的next数组,并设next[0]为-1。 前缀和后缀: 使用两个指针suffix(后缀)和prefix(前缀),分别从T的最后一个字符开始,向前比较对应位置的字符。 匹配字符: 如果当前字符匹配,prefix和suffix均加1,记录下一个匹配位置。 失配处理: 如果不匹配,使用next数组中的当前指针回溯到前一个匹配点,继续比较。 初始化: 同时初始化i和j指针为0,获取模式串T的next数组。 字符比较: 如果当前字符匹配,i和j均前进。 失配处理: 如果不匹配,利用next数组调整j指针,无需i回溯。 终止条件: 检查j是否等于T的长度,返回匹配位置或-1。
发布日期:2021-05-19 23:24:43
浏览次数:19
分类:精选文章
本文共 2790 字,大约阅读时间需要 9 分钟。
字符串匹配的KMP算法
朴素模式匹配算法
在进行模式匹配之前,我们需要了解什么是模式匹配。模式匹配,又称串匹配,是将模式串T从目标串S中搜索的过程。通常,主串称为目标串S,模式串称为T。以下是朴素的模式匹配算法(BF算法)的实现过程:
BF算法实现
public static int violentMatching(String s, String t) { int i = 0; int j = 0; while (i < s.length() && j < t.length()) { if (s.charAt(i) == t.charAt(j)) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j == t.length()) { return i - j; } else { return -1; }}
问题分析:
尽管BF算法实现简单,但它存在效率低下的问题。例如,当模式串与主串在某个位置不相同时,BF算法会从目标串的下一个字符重新开始比较,这可能导致大量不必要的比较操作。
KMP算法:优化模式匹配
KMP算法通过预处理模式串T,构建一个辅助数组next,使得在匹配过程中能够快速定位下一个比较的位置,无需对主串S进行回溯。具体来说,KMP算法的优化措施包括:
next数组的构建
public static int[] getNext(String t) { int[] next = new int[t.length()]; int suffix = 0; int prefix = -1; next[0] = -1; while (suffix < t.length() - 1) { if (prefix == -1 || t.charAt(prefix) == t.charAt(suffix)) { prefix++; suffix++; next[suffix] = prefix; } else { prefix = next[prefix]; suffix++; if (t.charAt(prefix) == t.charAt(suffix)) { prefix++; suffix++; next[suffix] = prefix; } else { next[suffix] = -1; } } } return next;}
解释:
KMP匹配过程
public static int KMP(String s, String t) { int i = 0; int j = 0; int[] next = getNext(t); while (i < s.length() && j < t.length()) { if (j == -1 || s.charAt(i) == t.charAt(j)) { i++; j++; } else { j = next[j]; } } if (j == t.length()) { return i - j; } else { return -1; }}
解释:
优化版本:处理特殊情况
public static int[] getNext(String t) { int[] next = new int[t.length()]; int[] maxLen = new int[t.length()]; int suffix = 0; int prefix = -1; next[0] = -1; while (suffix < t.length() - 1) { if (prefix == -1 || t.charAt(prefix) == t.charAt(suffix)) { prefix++; suffix++; next[suffix] = prefix; } else { next[suffix] = next[prefix]; if (t.charAt(prefix) != t.charAt(suffix)) { prefix = -1; } else { suffix++; prefix++; } } } return next;}
改进点:
- 当字符相同时,利用旧next值继续比较,避免不必要的回溯。
- 处理字符不匹配的情况,直接跳转到下一个位置,确保高效匹配。
总结
KMP算法通过预处理模式串T,构建next数组来优化模式匹配过程。这种预处理使得算法在匹配过程中无需对主串S进行回溯,只需对模式串T进行回溯,从而显著提升了效率。KMP算法的优化使它成为处理大规模字符串匹配问题的首选算法。
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2025年05月09日 01时54分22秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Windows下配置单机Hadoop环境 pyspark
2019-03-17
git教程之远程仓库
2019-03-17
Vue路由跳转如何传递一个对象过去?
2019-03-17
sockjs-node/info?t=1462183700002 报错解决方案
2019-03-17
解决VS Code保存时候自动格式化
2019-03-17
FI 替代相关 OSS Note 要点记录
2019-03-17
Problem K: 三角形数
2019-03-17
蓝桥杯---试题 算法提高 欧拉函数(数学)
2019-03-17
Math中的小算法
2019-03-17
Hidden treasures of the Rust ecosystem
2019-03-17
Rust异步浅谈
2019-03-17
man工具
2019-03-17
【网络加速】TensorRT7-开发指南中文_Plus版【1】
2019-03-17
SaltStack about The Top File 使用知识介绍
2019-03-17
网络协议和支持(一)、uuid模块
2019-03-17
numpy.vstack
2019-03-17
numpy.frombuffer()
2019-03-17