字符串hash

什么是hash 

Hash是把任意长度的输入(又叫做预映射pre-image) 算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

进制哈希

我们计算机中常用的为进制哈希

步骤:

  1. 首先定义一个进制数base,并设一个模数mod,mod最好大一些。base和mod最好互质。
  2. 枚举字符串的每一位,与base^i相乘加到ans里,注意对mod取模。比如字符串“ABCDE", base=26, mod=1e9+7
  3. ans=(A*base^4+B*base^3+C*base^2·+D*base^1+E*base^0)%mod

参考学习:F02 字符串哈希_哔哩哔哩_bilibili

哈希碰撞(冲突)

两个不同字符串拥有相同的hash值,在查询的时候,会认为这两个字符串相同,而其实他们不相同。

减少哈希冲突的概率:选取合适的base(通常选131,13331)、mod、双哈希

练习

- [P3370 【模板】字符串哈希](https://www.luogu.com.cn/problem/P3370)

题解:对每个字符串进制哈希,并将哈希值存到ans数组里,统计里面不一样的值的个数,输出即可。

代码实现如下:

#include<bits/stdc++.h>
using namespace std;
char s[1501];
long long ans[10001],hashe[10001][1501];
int main()
{
    int n,base=131,number=1,len=0;
    long long mod=1e9+7;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%s",s);
        len=strlen(s);
        //进制哈希
        for(int j=0; j<len; j++)
        {
            if(j==0)hashe[i][j]=s[j];
            else hashe[i][j]=(hashe[i][j-1]*base+s[j])%mod;
        }
        ans[i]=hashe[i][len-1];
    }
    sort(ans+1,ans+n+1);
    //统计数组ans中不相同的数字个数
    for(int i=1;i<n;i++)
    {
        if(ans[i]!=ans[i+1])
            number++;
    }
    printf("%d",number);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值