P3370 【模板】字串雜湊(Hash詳解)
阿新 • • 發佈:2018-12-17
題意:
給定N個字串(第i個字串長度為Mi,字串內包含數字、大小寫字母,大小寫敏感),請求出N個字串中共有多少個不同的字串。
單hash——模數19260817(80分)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const long long base=233;//進位制數:1、大於所有字元對應的數字的最大值;2、質數
const long long mod=19260817;//大質數(很關鍵)
char s[100005];
long long f[100005];
int n;
long long hash(char s[])
{
long long ans=0;
for(int i=0;i<strlen(s);i++)
{
ans=(ans*base+(long long)s[i])%mod;//雜湊其實就是把一個數轉化為一個值,注意在存入的時候取模
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
f[i]=hash(s);
}
sort (f+1,f+n+1);
int ans=1;
for(int i=2;i<=n;i++)
{
if(f[i]!=f[i-1]) ans++;
}
cout<<ans<<endl;
}
單hash——模數202370440130137957(AC) 推薦使用這種做法,一是簡潔好寫,二是誤差小,三是時間快(100ms)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const long long base=233;
const long long mod=212370440130137957ll;//記住這個數字
char s[100005];
long long f[100005];
int n;
long long hash(char s[])
{
long long ans=0;
for(int i=0;i<strlen(s);i++)
{
ans=(ans*base+(long long )s[i])%mod;
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
f[i]=hash(s);
}
sort(f+1,f+n+1);
int ans=1;
for(int i=2;i<=n;i++)
{
if(f[i]!=f[i-1]) ans++;
}
cout<<ans<<endl;
}
雙hash——模數19260817、19660813(AC) 時間較慢,有可能卡掉
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const long long base=233;
const long long mod1=19260817;
const long long mod2=19660813;//雙雜湊,模數取兩個互質大質數 19260817,19660813
char s[100005];
struct node
{
long long x,y;
}f[100005];
int n;
long long hash1(char s[])
{
long long ans=0;
for(int i=0;i<strlen(s);i++)
{
ans=(ans*base+(long long)s[i])%mod1;
}
return ans;
}
long long hash2(char s[])
{
long long ans=0;
for(int i=0;i<strlen(s);i++)
{
ans=(ans*base+(long long)s[i])%mod2;
}
return ans;
}
bool cmp1(node a,node b)
{
return a.x<b.x;
}
bool cmp2(node a,node b)
{
return a.y<b.y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
f[i].x=hash1(s);
f[i].y=hash2(s);
}
sort(f+1,f+n+1,cmp1);
sort(f+1,f+n+1,cmp2);//?
int ans=1;
for(int i=2;i<=n;i++)
{
if(f[i].x!=f[i-1].x || f[i].y!=f[i-1].y) ans++;
}
cout<<ans<<endl;
}