[JAVA][算法] [字符串匹配]KMP

我们为什么需要KMP?

字符串匹配问题中,我们需要找到匹配串pattern在原串text中的位置,一种显而易见的思路就是暴力匹配,如图所示,我们把pattern放置到text中的每个位置进行比较即可。

在这里插入图片描述

但是大家可以发现,这种方式的时间复杂度太高了,达到了O(pattern.length * text.length),我们是否可以进一步进行优化呢?在第一次匹配时,abaa和abab的最后一个字符不匹配,前面aba都匹配好了,移动了一位之后,发现前面又匹配不上了,这次移动相当于多此一举。换句话说,我们每次移动应当让前面仍然保持匹配状态,直接比较后面的位置。

本例中应当直接移动两位,让aaab和abaa比较,这也就是KMP的基本思想了。
在这里插入图片描述

基础知识

在这里插入图片描述

求匹配数组maxMatchLens

那么我们如何做到在移动的过程中保证前面的匹配状态呢?下图可以清晰地描述:
在这里插入图片描述
发生匹配错误的字符为c,左端为abab,在移动的时候,要保证真前缀和真后缀相等且长度最大(选了较小的会忽略可能正确的结果),对于abab:

真前缀:a ab aba
真后缀:b ab bab

也就是说,我们需要找到pattern中所有位置,相匹配的真前缀与真后缀中,最长的字符串的长度,这也就是我们经常听到的next数组了,这里我们用maxMatchLens来表示,如下图所示的例子中,假设我们已经求出来前面所有的值了,最后一个值如何求解呢?

在这里插入图片描述
举例: 第五位 c
在这里插入图片描述

c各参数取值Value c1Value c2Value c3
currentLen210
pattern.charAt(currentLen)aba
i444
pattern.charAt(i)ccc
处理1.while字符不相等1.while字符不相等3.赋值 maxMatchLens[4] = currentLen=0;
private int[] getMaxMatchLens(String pattern) {int[] maxMatchLens = new int[pattern.length()];int currentLen = 0;for (int i = 1; i < pattern.length(); i++) {while (currentLen > 0 && pattern.charAt(i) != pattern.charAt(currentLen)) {currentLen = maxMatchLens[currentLen - 1];}if (pattern.charAt(i) == pattern.charAt(currentLen)) {currentLen++;}maxMatchLens[i] = currentLen;}return maxMatchLens;
}

KMP匹配

返回起始坐标 (text里面找pattern)
匹配的思路与求maxMatchLens的思路基本一致,即按照最长、次长的顺序进行移位匹配,代码如下:


private List<Integer> search(String text, String pattern) {List<Integer> res = new ArrayList<>();int[] maxMatchLens = getMaxMatchLens(pattern);int j = 0;for (int i = 0; i < text.length(); i++) {while (j > 0 && text.charAt(i) != pattern.charAt(j)) {j = maxMatchLens[j - 1];}if (pattern.charAt(j) == text.charAt(i)) {j++;}if (j == pattern.length()) {res.add(i - j + 1);j = maxMatchLens[j - 1];}}return res;
}

参考链接:https://leetcode-cn.com/problems/longest-happy-prefix/solution/ni-zhen-de-li-jie-kmpma-jiao-ni-xun-su-zhang-wo-bi/
参考链接:https://blog.csdn.net/V_0617/article/details/79114860

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Leetcode][第309题][JAVA][最佳买卖股票时机含冷冻期][动态规划][压缩空间]

【问题描述】[中等] 【解答思路】 1. 动态规划 动态规划流程 第 1 步&#xff1a;设计状态 f[i]表示第 i 天结束之后的「累计最大收益」 第 2 步&#xff1a;状态转移方程 f[i][0]max(f[i−1][0],f[i−1][2]−prices[i]) f[i][1]f[i−1][0]prices[i] f[i][2]max(f[i−1][1]…

59 javabean的创建

在一个项目里定义一个java类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String g…

[剑指offer]面试题第[63]题[Leetcode][第121题][JAVA][买卖股票的最佳时机][动态规划][暴力]

【问题描述】[简单] 【解答思路】 1. 暴力 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) public class Solution {public int maxProfit(int prices[]) {int maxprofit 0;for (int i 0; i < prices.length - 1; i) {for (int j i 1; j < prices.leng…

60usebean创建实例对象

建立一个users的java类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPas…

ROS学习笔记四:用C++编写ROS发布与订阅

一、创建并编译功能包 1.1 创建功能包 在工作空间的 src 目录下创建功能包&#xff1a; $ cd ~/dev/catkin_ws/src $ catkin_create_pkg chapter2_tutorials std_msgs roscpp 1.2 编译功能包 进入工作目录下编译全部功能包&#xff1a; $ cd ~/dev/catkin_ws/ $ catkin_make 如…

[Leetcode][第315题][JAVA][计算右侧小于当前元素的个数][暴力][归并排序+索引数组]

【问题描述】[中等] 【解答思路】 1. 暴力 &#xff08;超时&#xff09; 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) public List<Integer> countSmaller(int[] nums) {List<Integer> ans new ArrayList<Integer>();int n nums.length…

61setproperty对象

建立一个users类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword(…

关于sin的导数的证明

引自JetTangs的博客 几何证明: AC切圆O于C AO交圆O于B CD、OF为水平线 BF为垂直线 令∠EOF θ 求证sinθ的导数为cosθ 证: 设∠AOC的角度为x, 由弦切角定理可知∠ACB 12x 而且∠ECDθ 则∠BCD 90-θ-12x 于是 limx→0sin(90−θ−12x)cosθ意思就是 当x无限接近于…

62 getproperty对象

定义一个login的jsp <% page language"java" import"java.util.*" contentType"text/html; charsetutf-8"%><!DOCTYPE html> <html> <head> <meta charset"ISO-8859-1"> <title>Insert title he…

Python网络爬虫之图片懒加载技术、selenium和PhantomJS

引入 今日概要 图片懒加载seleniumphantomJs谷歌无头浏览器知识点回顾 验证码处理流程今日详情 动态数据加载处理 一.图片懒加载 什么是图片懒加载&#xff1f; 案例分析&#xff1a;抓取站长素材http://sc.chinaz.com/中的图片数据 #!/usr/bin/env python # -*- coding:utf-8 …

[Leetcode][第题][JAVA][两个数组的交集 II1][双指针][HashMap]

【问题描述】[中等] 【解答思路】 1. 哈希映射 复杂度分析 class Solution {public int[] intersect(int[] nums1, int[] nums2) {if (nums1.length > nums2.length) {return intersect(nums2, nums1);}Map<Integer, Integer> map new HashMap<Integer, Intege…

63 javabean的作用域范围

定义一个users类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword(…

【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较...

样本&#xff1a;1MB的JSON文件&#xff0c;引入后生成500份的一个数组&#xff1b; 结果如下&#xff1a; 拷贝性能&#xff1a; JSON.parse(JSON.stringify()) 的方法&#xff1a;2523.55517578125ms immutable.fromJs: 1295.159912109375ms 快了一倍 深度比较性能&#xff1…

65 modol1用户登录

定义一个Users类 package srever;public class Users {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return passwor…

[剑指offer]面试题第[58-2]题[JAVA][左旋转字符串][拼接]

【问题描述】[中等] 【解答思路】 1. 字符串切片 应用字符串切片函数&#xff0c;可方便实现左旋转字符串。 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) public String reverseLeftWords(String s, int n) {return s.substring(n, s.length()) s.substring(0,…

[剑指offer]面试题第[59-1]题[Leetcode][第239题][JAVA][滑动窗口的最大值][单调队列][优先队列]

【问题描述】[困难] 【解答思路】 1. 暴力 两层 for 循环&#xff0c;每次都从窗口中找最大值即可 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N) public int[] maxSlidingWindow(int[] nums, int k) {int n nums.length;if (n 0) {return nums;}int result[]…

视图高级

目标 限制请求method页面重定向HttpRequest 对象HttpResponse 对象生产CVS 文件类视图错误处理一 限制请求method 1-1 常用的请求method 1. GET请求&#xff1a;GET请求一般用来向服务器索取数据&#xff0c;但不会向服务器提交数据&#xff0c;不会对服务器的状态进行更改。比…