P3370 [模板] 字符串哈希
2017-08-16 09:40
183 查看
传送门
对于字符串的处理方式有很多,HASH算是其中的一种暴力方法。
思想:通过某种方式在字符串和数字之间建立某种 一 一 对应的关系
比如’abcde’就可以看成
![](https://img-blog.csdn.net/20170816091311649?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzU5MTQ1ODc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
base是我们自定的一个数,类似于数中的进制,取决于判断的字符串不同字符的个数。
但是我们这样算出的HASH值有可能爆类型,于是要取模
这样算出的HASH值有如下性质
1:如果两个字符串HASH值不同,那么两个字符串一定不同
2:如果两个字符串HASH值相同,那么两个字符串可能相同,也可能不同(因为取模辣)
这样为防止出现不同但是HASH值相同的情况,我们可以使用双模数甚至是三模数,也可以使用无符号的长整型(自动溢出取模),对于模数,尽量取较大的质数,以尽肯能减少出现不同但是HASH值相同的情况。
常用的有 1e9+7,1e9+9
单哈希
双哈希
对于字符串的处理方式有很多,HASH算是其中的一种暴力方法。
思想:通过某种方式在字符串和数字之间建立某种 一 一 对应的关系
比如’abcde’就可以看成
base是我们自定的一个数,类似于数中的进制,取决于判断的字符串不同字符的个数。
但是我们这样算出的HASH值有可能爆类型,于是要取模
这样算出的HASH值有如下性质
1:如果两个字符串HASH值不同,那么两个字符串一定不同
2:如果两个字符串HASH值相同,那么两个字符串可能相同,也可能不同(因为取模辣)
这样为防止出现不同但是HASH值相同的情况,我们可以使用双模数甚至是三模数,也可以使用无符号的长整型(自动溢出取模),对于模数,尽量取较大的质数,以尽肯能减少出现不同但是HASH值相同的情况。
常用的有 1e9+7,1e9+9
单哈希
#include <cstdio> #include <iostream> #include <string> #include <algorithm> #include <cstring> #define LL long long using namespace std; const LL D1=131; const LL MOD1=1e9+7; LL hash1[10010]; char ss[10010]; LL make_hash1(char s[]) { LL ans=0; for(int i=0;i<strlen(s);i++) ans=(ans*D1+(LL)(s[i]))%MOD1; return ans; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",ss),hash1[i]=make_hash1(ss); sort(hash1+1,hash1+n+1); int ans=1; for(int i=2;i<=n;i++) if(hash1[i]!=hash1[i-1]) ans++; printf("%d",ans); return 0; }
双哈希
#include <cstdio> #include <iostream> #include <string> #include <algorithm> #include <cstring> #define LL long long using namespace std; const LL D1=131; const LL D2=131; const LL MOD1=1e9+7; const LL MOD2=1e9+9; char ss[10010]; struct node{ LL hash1,hash2; }a[10011]; LL make_hash1(char s[]) { LL ans=0; for(int i=0;i<strlen(s);i++) ans=(ans*D1+(LL)(s[i]))%MOD1; return ans; } LL make_hash2(char s[]) { LL ans=0; for(int i=0;i<strlen(s);i++) ans=(ans*D2+(LL)(s[i]))%MOD2; return ans; } bool comp(const node&a,const node&b) { return a.hash1<b.hash1; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",ss),a[i].hash1=make_hash1(ss),a[i].hash2=make_hash2(ss); sort(a+1,a+n+1,comp); int ans=1; for(int i=2;i<=n;i++) if(a[i].hash1!=a[i-1].hash1||a[i].hash2!=a[i-1].hash2) ans++; printf("%d",ans); return 0; }
相关文章推荐
- 洛谷 P3370 【模板】字符串哈希
- P3370 【模板】字符串哈希
- 洛谷——P3370 【模板】字符串哈希
- P3370 【模板】字符串哈希
- 字符串哈希-P3370 【模板】字符串哈希
- [P3370][模板]字符串哈希
- 【模板】字符串哈希
- luogu P3370 【模板】字符串哈希
- 【模板】字符串哈希
- 字符串哈希模板
- luogu3370 【模板】字符串哈希
- HDU4821-字符串哈希模板
- AC日记——【模板】字符串哈希 洛谷 3370
- 【字符串哈希】【BKDRhash】【Rabin-Karp算法】模板
- [模板]-字符串哈希
- 字符串哈希(Hash模板)
- 洛谷P3370 【模板】字符串哈希
- 【模板】【洛谷P3370】字符串哈希
- 【模板】字符串哈希
- 【模板】 字符串哈希