zoukankan      html  css  js  c++  java
  • 【模板】KMP字符串匹配

    给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

    为了减少骗分的情况,接下来还要输出子串的前缀数组next。

    朴素算法:暴力判断……复杂度为(O(m(n-1)))

    优化朴素算法:找到不同匹配点立即退出匹配 当然 这样最坏情况也会卡到(O(m(n-1)))

    (于是就被迫来学KMP)

    思路神奇的算法……模式串自己匹配自己)

    定义:失配 用模式串匹配原串 判到一个位置不能匹配就是失配

    如果我们扫原串的时候发现在某状态失配了的话,可以通过上面说的模式串自己匹配自己,来判断下一个可能的状态应该转移到哪里。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    #define MAXN 1000005
    #define scanf(a) scanf("%d",&a)
    #define print(a) printf("%d",a)
    #define print_(a) printf("%d ",a)
    #define printn(a) printf("%d
    ",a)
    #define endl printf("
    ");
    #define IMS char
    using namespace std;
    
    IMS a[MAXN],b[MAXN];
    int kmp[MAXN],lena,lenb;
    
    void init()
    {
    	cin>>a+1;
    	cin>>b+1;
    }
    void KMP()
    {
    	lena=strlen(a+1);
    	lenb=strlen(b+1);
    	int j=0;
    	for (int i=2;i<=lenb;i++)
    	{
    		while (j&&b[i]!=b[j+1])
    		{
    			j=kmp[j];
    		}
    		if (b[j+1]==b[i])
    		{
    			j++;
    		}
    		kmp[i]=j;
    	}
    }
    void start()
    {
    	int j=0;
    	for (int i=1;i<=lena;i++)
    	{
    		while (j>0&&b[j+1]!=a[i])
    		{
    			j=kmp[j];
    		}
    		if (b[j+1]==a[i])
    		{
    			j++;
    		}
    		if (j==lenb)
    		{
    			print(i-lenb+1);
    			endl;
    			j=kmp[j];
    		}
    	}
    	for (int i=1;i<=lenb;i++)
    	{
    		print_(kmp[i]);
    	}
    }
    
    int main()
    {
    	init();
    	KMP();
    	start();
    	return 0;
    }
    
  • 相关阅读:
    简易计算器
    方法的声明和使用
    真与假与c#,java中的不同之处
    SD卡添加文件,添加不进去,报 Read-only file system错误
    BitMap画图
    绘制一些基本图形(例如矩形,圆形,椭圆,多边形)
    SufaceView(绘图类)
    CanVas类(绘图类)
    回车键
    [动态规划][LIS+方案数]低价购买
  • 原文地址:https://www.cnblogs.com/Kan-kiz/p/10650590.html
Copyright © 2011-2022 走看看