【模板】字符串哈希

字符串哈希是用与比较两个字符串是否一样的算法,进行操作后比较的时间复杂度可以达到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);
posted @ 2020-10-06 21:49  一个经常掉线的人  阅读(215)  评论(0)    收藏  举报