ICode9

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

Kmp算法

2022-05-18 13:36:25  阅读:193  来源: 互联网

标签:前缀 int pattern prefix len 算法 Kmp table


算法代码笔记link:https://github.com/Gievance/DataStruct/blob/e010fff2ee4cb71c30504149e12e48ea52784bed/src/string/Kmp.java

算法流程:

---构建前缀表---
prefix_table(char[] pattern,int[] prefix,int n)
move_table(int[] prefix)
---KMP搜索---
kmp_search(char[] text,char[] pattern)

构建前缀表

prefix[0]默认为0
i从1开始遍历pattern

pattern[i]==pattern[len]时,采用的策略
len++;//最长公共前缀+1
prefix[i]=len;//记录当前i位置的前缀
i++;//向后移动1位
pattern[i]!=pattern[len]时,采用的策略
如果前缀值>0 ,则向左下移动
    len=prefix[len-1];
如果前缀值<=0,则记录前缀值,并右移
    prefix[i]=len;//len其实就是0
    i++;

KMP搜索

看代码吧..

完整KMP

public class Kmp {
/*
 *@func 构建前缀表
 *@param pattern:匹配字符数组,prefix:前缀表,n匹配字符数据的长度
 */
public static void prefix_table(char[] pattern,int[] prefix,int n){
    prefix[0] =0;//前缀表第一个初始为0
    int len =0;//len为前缀值,从0开始
    int i =1;//从第一个开始
    while(i<n){
        if(pattern[i]==pattern[len]){//当前字符与前缀值相同
            len++;
            prefix[i]=len;
            i++;
        }else{//当前字符与前缀值相同不同
            if(len>0)
                len=prefix[len-1];//左下移动,直到前缀值等于0
            else{
                prefix[i]=len;//前缀值为0,赋值给当前i的前缀值
                i++;//i右移
            }
        }
    }
}
/*
 *@func 完成前缀表的构建
 */
public static void move_table(int[] prefix){
    int len=prefix.length;
    for(int i=len-1;i>0;i--)
    {
        prefix[i]=prefix[i-1];
    }
    prefix[0]=-1;
}
public static void kmp_search(char[] text,char[] pattern){
    int n=text.length;//n =text的长度
    int m=pattern.length;//m=pattern的长度
    int i=0;//遍历text
    int j=0;//遍历pattern
    //构建前缀表
    int [] prefix=new int[m];
    prefix_table(pattern,prefix,m);
    move_table(prefix);

    while(i<n){//遍历text
        if(j==m-1&&text[i]==pattern[j])//当匹配到最后一个字符时
        {
            System.out.println("Found:"+(i-j));
            j=prefix[j];//继续向后匹配
        }
        if(text[i] == pattern[j])//对比相同
        {
            i++;
            j++;
        }else//对比不相同
        {
            j=prefix[j];
            if(j==-1)//当没有前缀值时,只需右移
            {
                i++;
                j++;
            }
        }
    }
}
public static void main(String[] args) {
    String text="ABABABCABAABABCABAA";
    String pattern="ABABCABAA";
    kmp_search(text.toCharArray(), pattern.toCharArray());

  }
}

参考文献:

https://www.bilibili.com/video/BV1Px411z7Yo/?spm_id_from=333.788.recommend_more_video.-1 ----KMP字符串匹配算法1
https://www.bilibili.com/video/BV1hW411a7ys/?spm_id_from=333.788.recommend_more_video.0 ----KMP字符串匹配算法2

标签:前缀,int,pattern,prefix,len,算法,Kmp,table
来源: https://www.cnblogs.com/alexanders/p/16284318.html

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

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

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

ICode9版权所有