zoukankan      html  css  js  c++  java
  • kmp算法

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

    模板串P在模式串S中多次作为子串出现。

    求出模板串P在模式串S中所有出现的位置的起始下标。

    输入格式

    第一行输入整数N,表示字符串P的长度。

    第二行输入字符串P。

    第三行输入整数M,表示字符串S的长度。

    第四行输入字符串S。

    输出格式

    共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。

    数据范围

    1N1041≤N≤104
    1M1051≤M≤105

    输入样例:

    3
    aba
    5
    ababa
    

    输出样例:

    0 2


    ##############################################

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 const int N = 1e4+10, M = 1e5+10;
     6 
     7 char p[N], s[M];
     8 int ne[N];//ne数组,代表从起点到长度为 i 的最长公共前后缀长度
     9 
    10 int main(){
    11     int n, m;
    12     cin >> n >> p + 1 >> m >> s + 1;//下标从 1 开始
    13     ne[0] = 0;
    14     ne[1] = 0;
    15     for(int i = 2;i <= n;++ i){
    16         int tmp = i - 1;//找到i的前一个位置
    17         do tmp = ne[tmp];//求出从起点到i的前一个位置的最长公共前后缀
    18         while(tmp != 0 && p[i] != p[tmp + 1]);//因为最长公共前后缀等于0可能会导致死循环,
    19                                             //另外一个判断条件是i位置的数和最长公共前后缀的下一个数不相等
    20         if(p[i] == p[tmp + 1])ne[i] = tmp + 1;//下面的if else很巧妙的处理了使上面的循环退出的两种情形
    21         else ne[i] = 0;
    22     }
    23     //i 代表 s , j 代表 pat
    24     //用j+1去作比较,一个技巧(记住)
    25     for(int i = 1, j = 0;i <= m;++i){
    26         if(s[i] == p[j+1]) ++j;
    27         else{
    28             do j = ne[j];
    29             while(j != 0 && p[j + 1] != s[i]);
    30             if(p[j + 1] == s[i]) ++j;
    31             else j = 0;
    32         }
    33         if(j == n){
    34             cout << i - n<< " ";
    35             j = ne[j];
    36         }
    37     }
    38     
    39     
    40     return 0;
    41 }
    View Code

    end

  • 相关阅读:
    jvm调优
    Spring 事务
    Spring Framework入门介绍
    redis入门介绍
    Spring与SpringMVC重复扫描问题
    跨域相关问题
    Spring MVC介绍
    Servlet、Servlet容器
    获取屏幕宽高
    mybatis中比较符的写法
  • 原文地址:https://www.cnblogs.com/sxq-study/p/12216098.html
Copyright © 2011-2022 走看看