1. 程式人生 > >字符串哈希

字符串哈希

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;
}

  

  

字符串哈希