• 字符串的查找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
  • 相关阅读:
    测试成功的Python中文文件读写脚本
    Solaris 10上Matlab 7(R14)安装手记
    人生:对心物互作的反应
    破解windows登录密码的有效方法
    Java实现二维码QRCode的编码和解码
    java调用储存过程的方法
    Java多态性的两个特殊情况
    Java中的TCP/UDP网络通信编程
    C语言之详解#ifdef等宏及妙用
    26个Jquery使用小技巧
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10484824.html
Copyright © 2020-2023  润新知