zoukankan      html  css  js  c++  java
  • 利用FFT来进行字符串匹配

    给定串A和串B,A由26个小写字母构成,B由?和26个小写字母构成

    ?可以和任意字符匹配

    求A中出现了多少次B

    这里可以使用fft做法,定义向量A和向量B

    然后求A和rev(B)的卷积结果C

    C的第i-len(B)位就可以表示匹配结果

    如果C的第i-len(B)位恰好是B中除了?的字符个数,那么就是匹配成功

    这样复杂度就是O((n+m)*(logn + logm))

    注意要调整eps,当数据很大的时候,误差会比较大

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <complex>
    using namespace std;
    const double pi = acos(-1);
    const int maxn =  111111;
    typedef complex<double> Complex;
    const double eps = 1e-8;
    void DFT(Complex *a, int n, int t)
    {
        if(n == 1) return;
        Complex a0[n>>1], a1[n>>1];
        for(int i = 0; i < n; i += 2) a0[i>>1] = a[i], a1[i>>1] = a[i+1];
        DFT(a0, n>>1, t); DFT(a1, n>>1, t);
        Complex wn(cos(2*pi/n), t*sin(2*pi/n)), w(1, 0);
        for(int i = 0; i < (n>>1); i++, w *= wn) a[i] = a0[i] + w*a1[i], a[i+(n>>1)] = a0[i] - w*a1[i];
    }
    Complex a[maxn], b[maxn];
    int n1, n2, nn, c[maxn];
    double x;
    string s1, s2;
    int main()
    {
        freopen("a.txt", "r", stdin);
        cin>>s1>>s2;
        n1 = s1.length(); n2 = s2.length();
        int N = n2;
        for(int i = 0; i < n1; i++) x = 2*pi*(s1[i] - 'a')/26, a[i] = Complex(cos(x), sin(x));
        for(int i = 0; i < n2; i++)
            if(s2[i] != '?') x = 2*pi*(s2[i] - 'a')/26, b[i] = Complex(cos(-x), sin(-x));
            else b[i] = Complex(0, 0), N--;
        for(int i = 0; i < n2/2; i++) swap(b[i], b[n2-i-1]);
        n1--; n2--;
        nn = 1; while(nn <= n1+n2) nn <<= 1;
        DFT(a, nn, 1); DFT(b, nn, 1);
        for(int i = 0; i <= nn; i++) a[i] = a[i]*b[i];
        DFT(a, nn, -1);
        for(int i = 0; i <= n1+n2; i++) c[i] = abs(a[i].imag()) < eps ? (a[i].real()/nn + eps) : 0;
        int ans = 0;
        for(int i = n2; i <= n1; i++) if(c[i] == N) ans++;
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    字符串切片
    格式化输出
    原生链+对象冒充组合继承模式
    对象冒充继承和原生链实现继承的方法和问题
    xlwt使用
    xlrd使用
    pip安装插件库
    第一天入驻博客园
    2-2ARP概念
    1-14常用的应用层协议及应用
  • 原文地址:https://www.cnblogs.com/Saurus/p/6349419.html
Copyright © 2011-2022 走看看