知识点
一 .?字符串哈希函数构造?
一 .?字符串哈希函数构造?
字符串哈希通过牺牲很小的准确率,达到快速进行字符串匹配的效果?
例题:?洛谷 P3370 【模板】字符串哈希
题目描述
如题,给定?N?个字符串(第?i?个字符串长度为?,字符串内包含数字、大小写字母,大小写敏感),请求出?N?个字符串中共有多少个不同的字符串。
输入格式
第一行包含一个整数?N,为字符串的个数。
接下来?N?行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
输入 #1
5
abc
aaaa
abc
abcc
12345
输出 #1
4
说明/提示
对于 30%?的数据:,,。
对于 70%?的数据:,,。
对于 100%?的数据:,,。
?处理方法1:自然溢出法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll unsigned long long
using namespace std;
int n;
const int maxn=1e7+5,base=131; //base表示进制数
const ll int mod=19260817891;
ll int a[maxn]; //a[]即哈希表
int res=0;
char s[maxn];
inline ll int hash_check(char s[])
{
ll int len=strlen(s),ans=0;
for(int i=0;i<len;++i)
{
ans=ans*base+(ll)s[i]; //利用自然数溢出,即超过2*64自动溢出,节省时间
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%s",s);
a[i]=hash_check(s);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;++i)
{
if(a[i]!=a[i+1]) res++;
}
printf("%d",res);
return 0;
}
方法2:单hash表
该题与自然溢出唯一不同的地方是:在进行散列的时候,与一个很大的整数进行取模。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll unsigned long long
using namespace std;
int n;
const int maxn=1e7+5,base=131;
const ll int mod=19260817891;
ll int a[maxn];
int res=0;
char s[maxn];
inline ll int hash_check(char s[])
{
ll int len=strlen(s),ans=0;
for(int i=0;i<len;++i)
{
ans=(ans*base+(ll)s[i])%mod; //唯一的不同之处
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%s",s);
a[i]=hash_check(s);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;++i)
{
if(a[i]!=a[i+1]) res++;
}
printf("%d",res);
return 0;
}
|