1. package com.atguigu.kmp;
    2. /**
    3. * ClassName: <br/>
    4. * Description: <br/>
    5. * Date: 2021-03-08 10:40 <br/>
    6. * @project data_algorithm
    7. * @package com.atguigu.kmp
    8. */
    9. import java.util.Arrays;
    10. public class KMPAlgorithm {
    11. public static void main(String[] args) {
    12. // TODO Auto-generated method stub
    13. String str1 = "BBC ABCDAB ABCDABCDABDE";
    14. String str2 = "ABCDABD";
    15. //String str2 = "BBC";
    16. int[] next = kmpNext("ABCDABD"); //[0, 1, 2, 0]
    17. System.out.println("next=" + Arrays.toString(next));
    18. int index = kmpSearch(str1, str2, next);
    19. System.out.println("index=" + index); // 15了
    20. }
    21. //写出我们的kmp搜索算法
    22. /**
    23. *
    24. * @param str1 源字符串
    25. * @param str2 子串
    26. * @param next 部分匹配表, 是子串对应的部分匹配表
    27. * @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置
    28. */
    29. public static int kmpSearch(String str1, String str2, int[] next) {
    30. //遍历
    31. for(int i = 0, j = 0; i < str1.length(); i++) {
    32. //需要处理 str1.charAt(i) != str2.charAt(j), 去调整j的大小
    33. //KMP算法核心点, 可以验证...
    34. while( j > 0 && str1.charAt(i) != str2.charAt(j)) {
    35. j = next[j-1];
    36. }
    37. if(str1.charAt(i) == str2.charAt(j)) {
    38. j++;
    39. }
    40. if(j == str2.length()) {//找到了 // j = 3 i
    41. return i - j + 1;
    42. }
    43. }
    44. return -1;
    45. }
    46. //获取到一个字符串(子串) 的部分匹配值表
    47. public static int[] kmpNext(String dest) {
    48. //创建一个next 数组保存部分匹配值
    49. int[] next = new int[dest.length()];
    50. next[0] = 0; //如果字符串是长度为1 部分匹配值就是0
    51. for(int i = 1, j = 0; i < dest.length(); i++) {
    52. //当dest.charAt(i) != dest.charAt(j) ,我们需要从next[j-1]获取新的j
    53. //直到我们发现 有 dest.charAt(i) == dest.charAt(j)成立才退出
    54. //这时kmp算法的核心点
    55. while(j > 0 && dest.charAt(i) != dest.charAt(j)) {
    56. j = next[j-1];
    57. }
    58. //当dest.charAt(i) == dest.charAt(j) 满足时,部分匹配值就是+1
    59. if(dest.charAt(i) == dest.charAt(j)) {
    60. j++;
    61. }
    62. next[i] = j;
    63. }
    64. return next;
    65. }
    66. }