哈希算法 学习笔记1

今天听了洛谷的字符串课之后,对于自己好好学学字符串算法也有了更大的动力。
但由于比较弱,所以先从最最简单的一个开始。
也就是哈希算法。

哈希算法是什么?

它通过给每个字符串赋予一个「随机」生成的整数的方法,使得可以用更加快的效率实现字符串判重或者匹配字符串等等操作。
比如说如果有两个字符串S和S’(长度分别为L和L’),而我们要比较它们是否具有包含关系。
枚举这个公共字串的开头的话,复杂度是O(LL’)的,对于许多字符串题来说都太慢了过不去。
哈希算法相当于是把字符串表示成一个k进制数:
H(C)=(c1km1+c2km2+c3km3+...+cmb0)modh H ( C ) = ( c 1 k m − 1 + c 2 k m − 2 + c 3 k m − 3 + . . . + c m b 0 ) m o d h
其中k,h是大于字符串长度且互质的质数。
并且有一个滚动哈希的优化可以直接将字符串匹配的复杂度降到O(L+L’)
H(S[a+1...a+m])=(H(S[a...a+m1]ksakm+sa+m)) H ( S [ a + 1... a + m ] ) = ( H ( S [ a . . . a + m − 1 ] ∗ k − s a k m + s a + m ) )

有什么缺点吗?

有的,因为不同字符串的哈希值是有一定可能相等的,所以应该用一些奇怪的方法来判断哈希值相同的字符串到底是不是同一个字符串。(不过我暂时不会qwq)
但是,如果两个字符串的哈希值不相同,那么它们一定不是相同的字符串!

代码实现?

暂时只会最简单的。(这是洛谷上面哈希模版可以AC的代码)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const ull B = 127;//这是个超可爱的数字!并且还是个质数ww
ull mod=212370440130137957ll;//从dalao题解上面抄的大质数
ull h[1505];
ull hashh(char s[])
{
  int len=strlen(s);
  ull ans=0;
  for(int i=0;i<len;i++)
  ans=(ans*B+(ull)s[i])%mod;
  return ans;
}
int main()
{
  int n;
  scanf("%d",&n);
  char a[1505];
  for(int i=1;i<=n;i++)
  {
    scanf("%s",a);
    h[i]=hashh(a);
  }
  sort(h+1,h+n+1);
  int res=1;
  for(int i=2;i<=n;i++)
  {
    if(h[i]!=h[i-1]) res++;
  }
  printf("%d\n",res);
  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值