#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const double pi = acos(-1.0);
const int maxn = 1e6 + 10;
int sum[maxn];
int can[maxn][10];
int num[maxn];
char s[maxn], p[maxn];
int pre[maxn], nex[maxn];
struct cp
{
double r, i;
cp(double _r = 0, double _i = 0)
{
r = _r;
i = _i;
}
cp operator +(const cp &p) const
{
return cp(r + p.r, i + p.i);
}
cp operator -(const cp &p) const
{
return cp(r - p.r, i - p.i);
}
cp operator *(const cp &p) const
{
return cp(r * p.r - i * p.i, r * p.i + i * p.r);
}
};
cp a[maxn], b[maxn];
int get(char c)
{
if(c == 'A')
return 0;
else if(c == 'C')
return 1;
else if(c == 'G')
return 2;
else
return 3;
}
void change(cp y[], int len)
{
for(int i = 1, j = len / 2; i < len - 1; ++i)
{
if(i < j) swap(y[i], y[j]);
int k = len / 2;
while(j >= k)
{
j -= k;
k>>=1;
}
if(j < k)
j += k;
}
}
void fft(cp y[], int len, int op)
{
change(y, len);
for(int h = 2; h <= len; h<<=1)
{
cp wn(cos(-op * 2 * pi / h), sin(-op * 2 * pi / h));
for(int j = 0; j < len; j += h)
{
cp w(1, 0);
for(int k = j; k < j + h / 2; k++)
{
cp u = y[k];
cp t =w * y[k + h / 2];
y[k] = u + t;
y[k + h / 2] = u - t;
w = w * wn;
}
}
}
if(op == -1)
{
for(int i = 0; i < len; i++)
{
y[i].r /= len;
}
}
}
void conv(int n, int m, int len, int x)
{
for(int i = 0; i < n; i++)
{
a[i] = cp(can[i][x], 0);
}
for(int i = n; i < len; i++)
{
a[i] = cp(0, 0);
}
for(int i = 0; i < m; i++)
{
if(get(p[i]) == x) b[i] = cp(1, 0);
else b[i] = cp(0, 0);
}
for(int i = m; i < len; i++)
{
b[i] = cp(0, 0);
}
fft(a, len, 1);
fft(b, len, 1);
for(int i = 0; i < len; i++)
a[i] = a[i] * b[i];
fft(a, len, -1);
for(int i = 0; i < len; i++)
sum[i] += (int)(a[i].r + 0.5);
}
int main()
{
int n, m, k;
scanf("%d%d%d%s%s", &n, &m, &k, s, p);
int len = 1;
while(len < n * 2 || len < m * 2)
len<<= 1;
memset(pre, -1, sizeof(pre));
memset(nex, -1, sizeof(nex));
memset(can, 0, sizeof(can));
memset(sum, 0, sizeof(sum));
for(int i = 0; i < n; i++)
{
num[i] = get(s[i]);
int x = num[i];
can[i][x]= 1;
for(int j = 0; j < 4; j++)
{
if(~pre[j] && i - pre[j] <= k) can[i][j] = 1;
}
pre[x] = i;
}
for(int i = n - 1; i >= 0; --i)
{
int x = num[i];
for(int j = 0; j < 4; ++j)
{
if(~nex[j] && nex[j] - i <= k) can[i][j] = 1;
}
nex[x] = i;
}
reverse(p, p + m);
for(int i = 0; i < 4; ++i)
{
conv(n, m, len, i);
}
int ans = 0;
for(int i = 0; i < n + m - 1; i++)
{
if(sum[i] == m)
ans++;
}
printf("%d\n", ans);
return 0;
}
再来一个fft字符串匹配 Fuzzy Search
猜你喜欢
转载自blog.csdn.net/weixin_43891021/article/details/102575064
今日推荐
周排行