zoukankan      html  css  js  c++  java
  • 字符串的查找KMP

    基本思想,当出现不匹配的时候,就知晓一部分文本内容(因为在匹配失败前已经发生匹配)

    P[0 ~ k-1] == P[j-k ~ j-1]

    //KMP
    #include<iostream>
    #include<string.h> 
    #include<malloc.h> 
    using namespace std;
    void come(string pattern,int next[]){
            int i=1;
        int j=-1;
        const int m=pattern.length();
        next[0]=j;//第一个为0 
        for(int i=1;i<m;i++){
            while(j>-1&&pattern[j+1]!=pattern[i]) j=next[j]; //恢复0 恢复的地方 
            if(pattern[i]==pattern[j+1]) j++;
            next[i]=j;
        }
    }
    /*void com(const char *pattern,int next[]){ //当匹配后跳转的地方next[i]----->pattern[j] 
        int i=1;
        int j=-1;
        const int m=strlen(pattern);
        next[0]=j;//第一个为0 
        
        for(int i=1;i<m;i++){
            while(j>-1&&pattern[j+1]!=pattern[i]) j=next[j]; //恢复0 恢复的地方 
            if(pattern[i]==pattern[j+1]) j++;
            next[i]=j;
        }
    } */
    /*int kmp(const char *text,const char *pattern){
        int i;
        int j=-1;
        const int n=strlen(text);
        const int m=strlen(pattern);
        if(n==0&&m==0) return 0;
        if(m==0)  return 0;
        int *next=(int*)malloc(sizeof(int)*m);
        com(pattern,next);
        for(i=0;i<n;i++) {
            while(j>-1&&pattern[j+1]!=text[i])  j=next[j];
            if(text[i]==pattern[j+1]) j++;
            if(j==m-1) {
                free(next);
                return i-j;
            }
        }
        free(next);
        return -1;
    }*/
    int Kmp(string text,string pattern){
        int i;
        int j=-1;
        const int n=text.length();
        const int m=pattern.length();
        if(n==0&&m==0) return 0;
        if(m==0)  return 0;
        int next[m];
        come(pattern,next);
        for(i=0;i<n;i++) {
            while(j>-1&&pattern[j+1]!=text[i])  j=next[j];
            if(text[i]==pattern[j+1]) j++;
            if(j==m-1) {
    //            free(next);
                return i-j;
            }
        }
    //    free(next);
        return -1;
    }
    int main()
    {
    //    char text[]="ABC ABCDA ABCDABCDABCDABDE";
    //    char pattern[]="ABCDABD";
    //    char *ch=text;
        string text="ABC ABCDA ABCDABCDABCDABDE";
        string pattern="ABCDABD";
        int i=Kmp(text,pattern);
    //    if(i>=0) printf("%s
    ",ch+i);
         cout<<i<<endl;
        return 0;
    }
    View Code

     我不晓得看了多少次kmp算法了,感觉还是要写博客,不然的话算法这个东西,太容易忘记了。。。

    分析:

    文本字符串长度为n,模式串长度为m,创建数组next[0...m-1],做一个标记,是对自身的标记

    //KMP
    #include<iostream>
    #include<string.h> 
    #include<malloc.h> 
    using namespace std;
    void come(string pattern,int next[]){
            int i=1;
        int j=-1;
        const int m=pattern.length();
        next[0]=j;//第一个为-1 0-(-1)==1 转移1 
        for(int i=1;i<m;i++){
            while(j>-1&&pattern[j+1]!=pattern[i]) j=next[j]; //恢复0 恢复的地方 
            if(pattern[i]==pattern[j+1]) j++;
            next[i]=j;
        }
    }
    
    int Kmp(string text,string pattern){
        int i;
        int j=-1;
        const int n=text.length();
        const int m=pattern.length();
        if(n==0&&m==0) return 0;
        if(m==0)  return 0;
        int next[m];
        come(pattern,next);
        for(i=0;i<n;i++) {
            if(j>-1&&pattern[j+1]!=text[i])  j=next[j];
            if(text[i]==pattern[j+1]) j++;
            if(j==m-1) 
                return i-j;
        }
        return -1;
    }
    int main()
    {
        string text="ABC ABCDA ABCDABCDABCDABDE";
        string pattern="ABCDABD";
        int i=Kmp(text,pattern);
         cout<<i<<endl;
        return 0;
    }
    View Code

     测试数据:

    ABC ABCDA ABCDABCDABCDABDE
    ABCDABD
    View Code
  • 相关阅读:
    Laravel笔记
    Mysql函数大全
    nginx中文文档
    解析富文本框
    VSCode的C++环境配置,多cpp在同一文件夹(json方式)
    UltraISO光盘刻录
    plog日志库(c++)
    .NET Core安装
    Halcon深度学习——奇异值检测
    C++命名规范
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10484824.html
Copyright © 2011-2022 走看看