字符串哈希
#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
using namespace std;
const int N = 10000 + 10;
const int base = 29;
const int mod1 = 1e9+7;
const int mod2 = 19260817;
int n; char s[N];
ll q_pow(ll a, int p, ll mod) {
if(p == 0) return 1;
ll ret = 1;
for(; p; p >>= 1) {
if(p&1) ret = ret*a%mod;
a = a*a%mod;
}
return ret;
}
struct Hash {
ll x, y;
}hash[N];
ll pow[2][1510];
bool cmp(const Hash& a, const Hash& b) {
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
void pre() {
pow[0][0] = pow[1][0] = 1;
for(int i = 1; i <= 1500; ++i) {
pow[0][i] = pow[0][i-1]*base%mod1;
pow[1][i] = pow[1][i-1]*base%mod2;
}
}
int main() {
pre();
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%s", s);
int len = strlen(s);
for(int j = 0; j < len; ++j) {
hash[i].x += pow[0][j]*((int)(s[j]))%mod1;
hash[i].y += pow[1][j]*((int)(s[j]))%mod2;
}
}
sort(hash+1, hash+n+1, cmp);
int ans = 1;
for(int i = 1; i < n; ++i) {
while(hash[i].x == hash[i+1].x && hash[i].y == hash[i+1].y) i++;
if(i == n) break;
ans++;
}
printf("%d\n", ans);
return 0;
}
KMP(正儿八经)
#include<cstdio>
#include<cstring>
const int N = 1e6 + 10;
char s[N], t[N];
int nxt[N], slen, tlen;
void get_nxt() {
nxt[1] = 0;
for(int i = 2; i <= tlen; ++i) {
int j = nxt[i-1];
while(j && t[j+1] != t[i]) j = nxt[j];
if(t[j+1] == t[i]) ++j;
nxt[i] = j;
}
}
void match() {
int j = 0;
for(int i = 1; i <= slen; ++i) {
while(j > 0 && t[j+1] != s[i]) j = nxt[j];
if(t[j+1] == s[i]) j++;
if(j == tlen) {
printf("%d\n", i-tlen+1);
j = nxt[j];
}
}
}
int main() {
scanf("%s%s", s+1, t+1);
slen = strlen(s+1); tlen = strlen(t+1);
get_nxt();
match();
for(int i = 1; i <= tlen; ++i) printf("%d ", nxt[i]);
return 0;
}
strstr
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e6 + 10;
char s[N], t[N];
int main() {
scanf("%s%s", s+1, t+1);
int pos = 0;
while(strstr(s+1+pos, t+1) != NULL) {
pos = strstr(s+1+pos, t+1) - s;
printf("%d\n", pos);
}
return 0;
}