【模板】字符串哈希
字符串哈希是用与比较两个字符串是否一样的算法,进行操作后比较的时间复杂度可以达到O(1)。
其原理也十分简单,将每一个字符串视为一个数字。这样在比较时只要比较两个字符串对应的数字是不是一样即可。实现的原理是构建一个X进制(x为素数)的数字,同时由于x在过大的情况会导致数据爆了。所以我们一般会选择一个非常大的模数,可以直接使用C++的unsigned long long,其效果是超过long long 范围时自动取模。
最后由于取模的原因,可能会在极低概率下情况出现hash冲突(两个不同的字符串对应一个数据)。可以采用双hash法(,双Hash就是对一个hash值用两个不同的质数进行两次mod操作,然后最后用一对数<hash1[n],hash2[n]>来表示一个字符串的哈希值,这样的一对数的重复几率加上选择较大的质数,冲突率几乎为0。)
以及X的选择 一般使用131 1331 133331这种数据(科学研究的结果 出现冲突概率会比较低)
例题[洛谷P3370](https://www.luogu.com.cn/problem/P3370)
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
ull base=13331;
ull hashcode;
string s;
ull a[15005];
int n,temp,ans;
void hash(string s){
hashcode=s[0];
for(int i=1;i<s.length();i++){
hashcode+=hashcode*base+(ull)s[i];//进制转换 比如10进制的120=(1*10+2)*10 以此类推到X进制转换
}
a[temp++]=hashcode;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>s;
hash(s);
}
sort(a,a+temp);
for(int i=0;i<temp;i++){
if(a[i]!=a[i+1]) ans++;
}
cout<<ans;
return 0;
}
// freopen("testdata.in", "r", stdin);

浙公网安备 33010602011771号