字符串哈希
阿新 • • 發佈:2018-12-31
d+ com amp fine 解決辦法 def 字母 簡單的 csharp
當比較兩個字符串是否相等的時候,最簡單的方法是逐個字母去比較,但是有時候這樣會太慢,如果我們將每個字符對應於一個26進制的數字,這樣的比較的復雜度就是O(1)。但是問題也來了,如果字符串比較長,我們對應的數字也就特別大,比long long 的範圍還大怎麽辦?
解決辦法是對哈希值取模,明顯這樣可能會產生沖突,那麽我們就暴力的對應兩個哈希值,這樣大大的減少了沖突的概率,雖然概率很小,但是如果字符串很多的話,失誤的概率還是很大的,措施1,mod取大,措施2,對應兩個哈希值
例題:http://codeforces.com/contest/514/problem/C
代碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull long long const int maxn=6e5+10; const ll mod=1e14+7; ull seed=1331,T[maxn]; char word[maxn]; map<ull,bool>ma; ull gethash() { ull res=0; int len=strlen(word); for(int i=0; word[i]; i++) { res+=word[len-i-1]*T[i]; res%=mod; } return res; } bool quer() { ull ha=gethash(); int len=strlen(word); for(int i=0; word[i]; i++) { int w=word[i]; for(int j=‘a‘; j<=‘c‘; j++) { if(w==j)continue; ull p=((j-w)*T[len-i-1]%mod+ha+mod)%mod; if(ma[p])return 1; } } return 0; } int main() { int n,m; T[0]=1; for(int i=1; i<maxn; i++) { T[i]=T[i-1]*seed%mod; } scanf("%d %d",&n,&m); for(int i=1; i<=n; i++) { scanf("%s",word); ma[gethash()]=1; } for(int i=1; i<=m; i++) { scanf("%s",word); if(quer()) printf("YES\n"); else printf("NO\n"); } return 0; }
字符串哈希