String Match

#include <stdio.h>
#include <math.h>

#define pln printf("\n");
#define p(a)  printf("%f ", a);

int N, M, K;
int t;
int n;
char    S[1000000];
char   tT[1000000];
char    T[1000000];
int   res[1000000];
int  alpS[1000000];
int  alpT[1000000];
const double pi = acos (-1.0);

struct Complex {
    double r, i;
    Complex(double r = 0, double i = 0) : r(r), i(i) {
        //
    };
    Complex operator+ (const Complex &b) {
        return Complex (r + b.r, i + b.i);
    }
    Complex operator- (const Complex &b) {
        return Complex (r - b.r, i - b.i);
    }
    Complex operator* (const Complex &b) {
        return Complex (r * b.r - i * b.i, i * b.r + r * b.i);
    }
} convANS[1000000], extA[1000000], extB[1000000];

int calculateMatchPosition();
    void setStringS(char);
    void setStringT(char);
    void conv();
        void reverse(Complex[], int);
        void fft(Complex[], int);
        void ifft(Complex[], int);
            void _ifft(Complex[], int);

int main() {

    scanf("%d", &N);
    scanf("%d", &M);
    scanf("%d", &K);



    t = N + M;
  //  n = (int) pow(2.0, ceil( log(t) / log(2.0) ));
    int tmp = 1;
    n = 0;
    while(tmp <= N + M - 2){
        tmp *= 2;
        ++n;
    }
    n = pow(2.0, n);

    printf("%d %d",N, n);
    pln


    scanf("%s",S);
    scanf("%s",tT);

    int ANS = calculateMatchPosition();

    printf("%d\n", ANS);

    return 0;
}
int calculateMatchPosition(){
    for(int i = 0; i < M; i++){
        T[i] = tT[M - 1 - i];
    }
    for(int i = 0; i < n; i++) {
        res[i] = 0;
    }
    char Alp[] = {'A', 'B', 'C', 'D', 'E'};
    for(int i = 0; i < 5; ++i){
        setStringS(Alp[i]);
        setStringT(Alp[i]);
        conv();
//        printf("%c",Alp[i]);
//        pln
        for(int j = M - 1; j < N; j++){
            res[j] += (int)(convANS[j].r + 0.5);
//          p(convANS[j].r + 0.5);
        }
//      pln
//      pln
    }
    int cnt = 0;

    for(int i = 0; i < n; ++i){
        if(res[i] == M) cnt++;
        //p(res[i]);
    }
  //  pln
    return cnt;
}
void setStringS(char a){
    for (int i = 0; i < N; ++i) alpS[i] = 0;
    for (int i = 0; i < N; ++i) {
        if(S[i] != a) continue;
        int p = i;
        //move left
        while(p >= 0 && p >= i - K) {
            alpS[p--] = 1;
        }
        //move right
        p = i;
        while(p < N && p <= i + K) {
            alpS[p++] = 1;
        }
    }
}
void setStringT(char a){
    for (int i = 0; i < M; ++i) alpT[i] = 0;
    for (int i = 0; i < M; ++i) {
        if(T[i] == a) alpT[i] = 1;
        else alpT[i] = 0;
    }
}
void conv(){

    for(int i = 0; i < N; ++i){
        extA[i].r = alpS[i]?1:0;
        extA[i].i = 0;
    }
    for(int i = N; i < n; ++i){
        extA[i].r = 0;
        extA[i].i = 0;
    }
    for(int i = 0; i < M; ++i){
        extB[i].r = alpT[i]?1:0;
        extB[i].i = 0;
    }
    for(int i = M; i < n; ++i){
        extB[i].r = 0;
        extB[i].i = 0;
    }

    fft(extA, n);
    fft(extB, n);
    for(int i = 0; i < n; i++){
        convANS[i] = extA[i] * extB[i];
    }
    ifft(convANS, n);
}
void ifft(Complex F[], int n){
    _ifft(F, n);
    for(int i = 0; i < n; i++){
        F[i].r /= n;
    }
}

void _ifft(Complex F[], int n){
    reverse(F, n);
    double t = -2.0 * pi;

    for(int h = 2; h <= n; h *= 2) {
        Complex wn (cos(t / h), sin(t / h));
        for(int j = 0; j < n; j += h) {
            Complex wk (1, 0);
            for(int k = j; k < j + h/2; ++k) {
                Complex u = F[k];
                Complex v = F[k + h/2] * wk;
                F[k]       = u + v;
                F[k + h/2] = u - v;
                wk = wk * wn;
            }
        }
    }
}

void fft(Complex F[], int n){
    reverse(F, n);
    double t = 2.0 * pi;

    for(int h = 2; h <= n; h *= 2) {
        Complex wn (cos(t / h), sin(t / h));
        for(int j = 0; j < n; j += h) {
            Complex wk (1, 0);
            for(int k = j; k < j + h/2; ++k) {
                Complex u = F[k];
                Complex v = F[k + h/2] * wk;
                F[k]       = u + v;
                F[k + h/2] = u - v;
                wk = wk * wn;
            }
        }
    }
//    for(int i = 0; i < n; i++)  p(F[i].r);
//    pln
}

bool hasSwap[1000000];

void reverse(Complex a[], int len){
    int a_length = len;
    int n = (int)(log(len) / log(2));
    len = n;

    //init
    for(int i = 0; i < a_length; i++) hasSwap[i] = false;

    for(int i = 1; i < a_length-1; ++i) {
        if(hasSwap[i]) continue;
        int A = i;
        int j = 0;
        while(len-- > 0) {
            j <<= 1;
            if( (A & 1) == 1) {
                j += 1;
            }
            A >>= 1;
        }

        hasSwap[i] = true;
        hasSwap[j] = true;
        //swap
//        swap(a[i], a[j]);
        Complex tmp (a[i].r, a[i].i);
        a[i] = a[j];
        a[j] = tmp;
        len = n;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值