字符串哈希

試著忘記壹切 提交于 2020-02-02 01:05:59

字符串Hash

字符串hash就是把一个字符串变成一个整数

当两个字符串相同时,它们通过hash计算后得到的整数相同,当两个字符串不同时,它们的数字就不同。

Hash公式

首先设一个进制数base,和一个取模数mod
给定一个字符串S

id(x)=x - ‘a’ + 1

*hash[ i ] =hash[ i -1 ] base + id(s[ i ])

hash冲突

比如orzc的哈希值为233,orzhjw的哈希值也为233
而这两个字符串显然不相同,这就叫hash冲突。

单hash方法

就是一个取模运算,只进行一次hash运算。公式如下:

*hash[i]=(hash[i-1]base+id(s[i]))%mod
单哈希的hash冲突概率很低

例:取base=13,mod=101, 对字符串abc进行hash
hash[0] = 1
hash[1] = (hash[0] * base +id(s[1]) % mod =15
hash[2] = (hash[1] * base + id[s[2]) % mod = 97
所以当base=13,mod=101时,可以把abc当作97,**即abc的hash值为97 **

代码如下:

    int n=strlen(s+1),base=13,mod=101;
    int hash[1001],id[1001];
    
    hash[0]=1;
    
    for(int i=1;i<n;i++)
    {
        id[i]=s[i+1]-'a'+1;
        
        hash[i]=(hash[i-1]*base+id[i])%mod;
    }
    
    printf("hash值为%d\n",hash[n-1]);

双hash方法

进行两次hash运算,两次hash进行比较,避免hash冲突
代码如下:

int n=strlen(s+1);
    int base1=131,mod1=11345646;
    int base2=131,mod2=12341654;
    int hash1[1001],id1[1001];
    int hash2[1001],id2[1001];
    hash[0]=1;
    for(int i=1;i<n;i++)
    {
        id1[i]=s[i+1]-'a'+1;
        hash1[i]=(hash1[i-1]*base1+id1[i])%mod1;
        id2[i]=s[i+1]-'a'+1;
        hash2[i]=(hash2[i-1]*base2+id2[i])%mod2;
    }
    if(hash1[n-1]==hash2[n-1])
   

https://www.acwing.com/problem/content/description/140/

兔子与兔子,求两个子串是否相同
代码如下:

#include<stdio.h>
#include<string.h>
#define N 1000001
char s[N];
unsigned long long int hash[N],str[N];
unsigned long long int fun(int x,int y)
{
    return hash[y]-hash[x-1]*str[y-x+1];
}
int main()
{
    int i,j;
    while(~scanf("%s",s+1))
    {
        int m,n;
        scanf("%d",&m);
        n=strlen(s+1);
        str[0]=1;
        for(i=1;i<=n;i++)
        {
            hash[i]=hash[i-1]*131+s[i]-'a'+1;
            str[i]=str[i-1]*131;
        }
        while(m--)
        {
            int l1,l2,r1,r2;
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            if(fun(l1,r1)==fun(l2,r2))
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!