ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

KMP算法

2022-04-30 17:35:46  阅读:177  来源: 互联网

标签:int str2 i2 next 后缀 算法 KMP 字符串


1.KMP算法解决的问题:两个字符串str1,str2,判断str2是否为str1的字串

* 注:abc是abcde的字串,但abd不是

 

2.KMP算法过程

(1).先求字符串前缀和后缀都相等的最大长度(该长度一定小于字符串本身的长度)
* 例:一个字符串abbab,则其前后缀分别为:
* 长度:1 2 3 4 5——等于字符串长度,前后缀对任何字符串都相等,无意义,不考虑
* 前缀:a ab abb abba
* 后缀:b ab bab bbab
* 所以得到最大的前后缀相等长度为2
*
(2).求得一个与字符串对应数组,该数组表示与数组同一位置得字符串的前缀的最大前后缀相等长度(即1过程的值)
* 例:字符串abbab,求得一个对应数组next,则:
* next[0] = -1(字符串0位置前没有字符串), next[1] = 0(前缀字符串a的最大前后缀相等长度为0)
* next[2] = 0(求字符串ab) next[3] = 0(求字符串abb) next[4] = 1(求字符串abba)
*
* 快速求得next[]数组的方法(根据next[i - 1]的值来算next[i]的值)
* 设next[i - 1]的值为a1,则比较str[a1 + 1]与str[i - 1]是否相等,如果相等则next[i] = next[i - 1] + 1
* 如果不相等,则获取next[next[i - 1]]的值a2,比较str[a2 + 1]与str[i - 1]是否相等,如果相等,则:
* next[i] = next[next[i - 1]] + 1; 以此类推,直到得到的a(n)如果为-1,则next[i] = 0
*
(3).比较过程的实现:
* 先通过2过程得到str2的数组next,然后str1和str2开始遍历比较,当找到i位置第一个str1的一部分只部分相等于str2时
* 找到这个相等的str2字串str3,然后得到str3的最大前后缀相等的长度,就将这个后缀代替之前的前缀跟str1从产生不同
* 的位置开始继续往下比较即可
*
* 本质就是当str1与str2比较时,比较到一半发现只是部分相等时,充分利用了部分相等的特点,两者都从一个可行的特定
* 位置开始进行比较

 

代码及解析:

 1 public static int getIndexOf(String s,String m) {
 2         if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
 3             return -1;
 4         }
 5         char[] str1 = s.toCharArray();
 6         char[] str2 = m.toCharArray();
 7         int i1 = 0;
 8         int i2 = 0;
 9         int[] next = getNextArray(str2);
10         while (i1 < str1.length && i2 < str2.length) {
11             if (str1[i1] == str2[i2]) {
12                 i1++;
13                 i2++;
14             } else if (next[i2] == -1) {//当i2已经无法往前跳时,则只能i1往后,i2
15                 i1++;
16             } else {//根据前后缀相等,将它从前缀开始比转为从后缀开始比
17                 i2 = next[i2];
18             }
19         }
20         return i2 == str2.length ? i1 - i2 : -1;
21     }
22     
23     public static int[] getNextArray(char[] ms) {
24         if (ms.length == 1) {
25             return new int[] {-1};
26         }
27         int[] next = new int[ms.length];
28         next[0] = -1;
29         next[1] = 0;
30         int i = 2;
31         int cn = 0;//用来动态变化要处理的位置
32         while (i < next.length) {
33             if (ms[i - 1] == ms[cn]) {
34                 next[i++] = ++cn;
35             } else if (cn > 0) {
36                 cn = next[cn];
37             } else {
38                 next[i++] = 0;
39             }
40         }
41         return next;

 

标签:int,str2,i2,next,后缀,算法,KMP,字符串
来源: https://www.cnblogs.com/jue1e0/p/16210736.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有