一维hash
typedef long long ll;
typedef unsigned long long ull;
const int N = 1000000 + 10 , M = 10000 + 10 , INF = 0x3f3f3f3f ;
const int seed = 31 ;
char pat[M], ori[N];
ull Seed[N], hash_ori[N];
ull BKDRhash(char *str)
{
ull h = 0 ;
for (int i = 0 ; str[i]; i++)
h = h * seed + str[i];
return h;
}
int main()
{
Seed[0 ] = 1 ;
for (int i = 1 ; i < N; i++) Seed[i] = Seed[i-1 ] * seed;
int t;
scanf ("%d" , &t);
while (t--)
{
scanf ("%s%s" , pat+1 , ori+1 );
ull hash_pat = BKDRhash(pat+1 );
int len_pat = strlen (pat+1 );
hash_ori[0 ] = 0 ;
int ans = 0 ;
for (int i = 1 ; ori[i]; i++)
{
hash_ori[i] = hash_ori[i-1 ] * seed + ori[i];
int j = i - len_pat + 1 ;
if (j >= 1 )
{hash_ori[i] - hash_ori[j-1 ] * Seed[len_pat]是区间[j,i]的hash值,len_pat是区间长度
if (hash_ori[i] - hash_ori[j-1 ]*Seed[len_pat] == hash_pat) ans++;
}
}
printf ("%d\n" , ans);
}
return 0 ;
}
二维hash:
typedef unsigned long long ull;
const int N = 500 + 10 , INF = 0x3f3f3f3f ;
const int seed = 131 , Seed = 1789 ;
char ori[N][N];
ull hash1[N][N], seed_pow[N];
ull hash2[N][N], Seed_pow[N];
ull a[N*N];
int n, m;
bool check(int k)
{
int tot = 0 ;
for (int i = k; i <= n; i++)
{
for (int j = k; j <= m; j++)
{
ull tmp = hash2[i][j] - hash2[i-k][j] * Seed_pow[k] - hash2[i][j-k] * seed_pow[k] + hash2[i-k][j-k] * Seed_pow[k] * seed_pow[k];
a[++tot] = tmp;
}
}
sort(a + 1 , a + 1 + tot);
for (int i = 1 ; i <= tot-1 ; i++)
if (a[i] == a[i+1 ]) return true ;
return false ;
}
int main()
{
seed_pow[0 ] = Seed_pow[0 ] = 1 ;
for (int i = 1 ; i < N; i++)
{
seed_pow[i] = seed_pow[i-1 ] * seed;
Seed_pow[i] = Seed_pow[i-1 ] * Seed;
}
scanf ("%d%d" , &n, &m);
for (int i = 1 ; i <= n; i++) scanf (" %s" , ori[i] + 1 );
for (int i = 1 ; i <= n; i++)
for (int j = 1 ; j <= m; j++)
hash1[i][j] = hash1[i][j-1 ] * seed + ori[i][j];
for (int i = 1 ; i <= m; i++)
for (int j = 1 ; j <= n; j++)
hash2[j][i] = hash2[j-1 ][i] * Seed + hash1[j][i];
int ans = 0 ;
int l = 0 , r = min(n, m);
while (l <= r)
{
int mid = (l + r) >> 1 ;
if (check(mid)) ans = mid, l = mid + 1 ;
else r = mid - 1 ;
}
printf ("%d\n" , ans);
return 0 ;
}
ELFhash:
给出一些数字,求出这些数字中出现次数,输出最多的那个次数。其中数字不超过30 位
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned int ui;
const int N = 7003 , MOD = 7003 ;
int Hash[N], num[N];
int res;
int ELFhash(char *str)
{
ui h = 0 , g;
while (*str)
{
h = (h<<4 ) + *str++;
if ((g = h & 0xf0000000 ) != 0 )
{
h ^= g>>24 ;
h &= ~g;
}
}
return h;
}
void hash_table(char *str)
{
int k = ELFhash(str);
int t = k % MOD;
while (Hash[t] != k && Hash[t] != -1 ) t = (t + 1 ) % MOD;
if (Hash[t] == -1 ) num[t] = 1 , Hash[t] = k;
else res = max(res, ++num[t]);
}
int main()
{
int n;
char str[100 ];
while (~ scanf ("%d" , &n))
{
getchar();
res = 1 ;
memset (Hash, -1 , sizeof Hash);
for (int i = 1 ; i <= n; i++)
{
scanf ("%s" , str);
int j = 0 ;
while (str[j] == '0' ) j++;
hash_table(str + j);
}
printf ("%d\n" , res);
}
return 0 ;
}