• KMP模板


    打ACM的时候又碰到了kmp,就翻了翻以前的博客
    怎么说呢,感觉以前写的好烂啊,全是一些感性的理解,没有任何严格的证明,而且代码不是很简洁。
    所以这里推荐还是看书吧,比如李煜东的《算法竞赛进阶指南》就讲的很好,而且代码写的很精炼,我觉得如果我写这篇文章的话,也只不过是把书上的话复述一遍,所以这里我就贴一个代码吧。


    kmp推荐字符串从1开始标号,因为当f[i]=0的时候表示在模板串的当前位置,没有任何一个前缀能和对应的后缀匹配上,但如果从0开始标号的话就会引起歧义。
    题目就是洛谷的kmp板子

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1e6 + 5;
    
    char s[maxn], s2[maxn];
    
    int f[maxn];
    void kmp_init(char* s)
    {
    	int n = strlen(s + 1); f[1] = 0;
    	for(int i = 2, j = 0; i <= n; ++i)
    	{
    		while(j && s[j + 1] != s[i]) j = f[j];
    		if(s[j + 1] == s[i]) ++j;
    		f[i] = j;
    	}
    }
    void kmp(char* t, char* p, int* f)
    {
    	int n = strlen(t + 1), m = strlen(p + 1);
    	for(int i = 1, j = 0; i <= n; ++i)
    	{
    		while(j && (j == m || t[i] != p[j + 1])) j = f[j];
    		if(t[i] == p[j + 1]) ++j;
    		if(j == m) printf("%d
    ", i - j + 1);
    	}
    }
    
    int main()
    {
    	scanf("%s%s", s + 1, s2 + 1);
    	kmp_init(s2), kmp(s, s2, f);
    	int m = strlen(s2 + 1);
    	for(int i = 1; i <= m; ++i) printf("%d ", f[i]); puts("");
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 1103 Poi2007 大都市meg
    BZOJ 2815 ZJOI2012 灾难
    【bzoj】1046: [HAOI2007]上升序列
    P1168跳房子(焫鷄如我)
    HAIO2017[打酱油的旅行!?]
    [haoi2013]花卉节
    P1298(矩阵切割)DP
    P1216 (list加强版)
    p1219最佳贸易(两边bfs写的)
    p1150[noip2013普及]表达式求值
  • 原文地址:https://www.cnblogs.com/mrclr/p/14216422.html
Copyright © 2020-2023  润新知