# 杭电1686 kmp经典算法（kmp和hash大法好）

https://www.bilibili.com/video/av11866460/?from=search&seid=17168777339621646545

https://www.bilibili.com/video/av16828557/?from=search&seid=17168777339621646545

//这两个网站是讲kmp，强力推荐读者去看看；

//这个题给个样例

ababcabaa

#include <iostream>
#include <cstring>
#define maxn 1000010

typedef long long ll;

using namespace std;

ll NExt[maxn],n,m;
char a[maxn],b[maxn];
void Next()
{
ll i = 1, len = 0;
NExt[1] = 0;
while(i < m)
{
if(len == 0 || b[i] == b[len])
{
i++;
len++;
/*if(b[i] != b[len])*/NExt[i] = len;
/*else
{
next[i] = next[len];
}
*/
}
else
{
len = NExt[len];
}
}
}

void kmp()
{
Next();
ll i = 1;
ll j = 1;
ll to = 0;
while(i <= n)
{
if(j == m && a[i] == b[j])
{
to++;
//cout << i - j + 1 << endl;
j = NExt[j];
}
if(j == 0 || a[i] == b[j])
{
i++;
j++;
}
else
{
j = NExt[j];
}
}
cout << to << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll t;
cin >> t;
while(t--)
{
cin >> (b + 1) >> (a + 1);
n = strlen(a + 1);
m = strlen(b + 1);
kmp();
}

return 0;
}


hash做法

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 233333;
using namespace std;

char a[maxn];
char b[maxn];
ull h1[maxn],f[maxn],h2[maxn];
int main()
{

ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);

ll t;
cin >> t;
while(t--)
{
cin >> (a + 1);
ll n = strlen(a + 1);
cin >> (b + 1);
ll m = strlen(b + 1);
for(int i = 1; i <= n; i ++)
{
h1[i] = h1[i - 1] * base + (a[i] - '0');
}

f[0] = 1;
for(int i = 1; i <= m; i ++)
{
h2[i] = h2[i - 1] * base + (b[i] - '0');
f[i] = f[i - 1] * base;
}

ll ans = 0;
for(int i = 1; i + n - 1 <= m; i ++)
{
ll r = i + n - 1;
if(h2[r] - h2[i - 1] * f[r - i + 1] == h1[n])
{
ans ++;
}
}

cout << ans << endl;
}

return 0;
}


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客