zoukankan      html  css  js  c++  java
  • kmp算法(字符串匹配)

    参考视频:https://www.bilibili.com/video/BV1jb411V78H?from=search&seid=4313084886343126293

    参考博客:https://blog.csdn.net/qq_34181098/article/details/107066929

    next数组(模式串):

     1 void buildNext(string& p, int* Next, int n) {
     2     int x,y; // x指针指向前缀,y指向后缀
     3     x = -1;
     4     y = 0;
     5     while(y < n) { // n 为Next数组长度
     6         if(x == -1 || p[x] == p[y]) {
     7             Next[++y] = ++x; // x共用
     8         }
     9         else {
    10             x = Next[x]; 
    11         }
    12     }
    13 }

    kmp:

     1 int KMP(string t, string p) {
     2     int i = 0; // 主串位置
     3     int j = 0; // 模式串位置
     4     const int len = p.size() + 1;
     5     int next[len] = { -1 };
     6     buildNext(p,next,p.size());
     7 
     8     int tsize = t.size();
     9     int psize = p.size();
    10     // while 中的匹配方法是核心,前缀表生成和KMP本体匹配都用这个
    11     while(i < tsize && j < psize) {
    12         if(j == -1 || t[i] == p[j]) {
    13             /*
    14                 j = -1 时(next数组-1),直接匹配下一个位置。模式串index和next数组共用
    15             */
    16             i++;
    17             j++;
    18         }
    19         else {
    20             j = next[j]; // 如果匹配不上,则参照next数组表进行位移
    21         }
    22 
    23     }
    24     if( j == psize)
    25         return i - j;
    26     else
    27         return -1;
    28 }

    模板题:https://www.luogu.com.cn/problem/P3375

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 void build_next(char *s, int *next, int len) {
     6     int x = -1, y = 0;
     7     while(y < len) {
     8         if(x == -1 || s[x] == s[y])
     9             next[++y] = ++x;
    10         else
    11             x = next[x];
    12     }
    13 }
    14 
    15 void kmp(char *mstr, char *pstr) {
    16     int i = 0, j = 0;
    17     int mlen = strlen(mstr), plen = strlen(pstr) + 1;
    18     int next[plen] = {-1};
    19     build_next(pstr, next, plen);
    20     while(i < mlen) {
    21         if(j == -1 || mstr[i] == pstr[j]) {
    22             i++;
    23             j++;
    24         } else {
    25             j = next[j];
    26         }
    27         //cout << "#" << j << "#" << endl;
    28         if(j == plen - 1) {
    29             cout << i-j+1 << endl;
    30             j = next[j];
    31         }
    32     }
    33     for(int i = 1; i < plen;i++) {
    34         if(i != 1) cout << " ";
    35         cout << next[i];
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     char *s1 = new char[1000000], *s2 = new char[1000000];
    42     cin >> s1; cin >> s2;
    43     kmp(s1, s2);
    44     return 0;
    45 }
  • 相关阅读:
    软件层次结构
    PHP 配合Cross-Origin Resource Sharing实现跨域 使用心得
    C语言 标准I/O库函数 fgets 使用心得
    PHP 逗号运算符 的作用
    PHP 函数 array_map 使用心得
    PHP 函数 htmlspecialchars 使用心得
    Go语言特性学习
    curl文件上传类
    php 协程理解
    php 分词扩展 scws
  • 原文地址:https://www.cnblogs.com/knightoflake/p/13604718.html
Copyright © 2011-2022 走看看