字符串hash——学习笔记

# 字符串Hash——学习笔记1

字符串hash是一种非常简单的字符串操作。其本质就是通过,某种方式对字符串单向加密,把不同的字符串尽量转换成不同的整数。在洛谷的P3370字符串hash模板题中,我们可以了解到,hash一个最基本的功能就是判别不同字符串。

## 单哈希

顾名思义,就是对于每一个字符串有一个哈希值。

设 X[MAXN] 是一个字符串,对于这个字符串中的每一个字符,可将其转换为(unsigned long long)X[i](结果就是其ASCLL码的值),它的单哈希公式为:

```cpp
ans=(ans*p+(unsigned long long)x[i])%mod+prim;
```


注:其中的p,mod和prim都是质数,而且mod可以很大(一般都很大)

## 上题目:

如题,给定 $N$ 个字符串(第 $i$ 个字符串长度为 $M_i$,字符串内包含数字、大小写字母,大小写敏感),请求出 $N$ 个字符串中共有多少个不同的字符串。

 

第一行包含一个整数 $N$,为字符串的个数。

接下来 $N$ 行每行包含一个字符串,为所提供的字符串。

 

输出包含一行,包含一个整数,为不同的字符串个数。

 

```
5
abc
aaaa
abc
abcc
12345
```

```
4
```

## 提示

对于 $30\%$ 的数据:$N\leq 10$,$M_i≈6$,$Mmax\leq 15$。

对于 $70\%$ 的数据:$N\leq 1000$,$M_i≈100$,$Mmax\leq 150$。

对于 $100\%$ 的数据:$N\leq 10000$,$M_i≈1000$,$Mmax\leq 1500$。

## 解题:

这就是刚刚上文提到的字符串hash的最基本的操作“字符串判重”。直接遍历n,套用单哈希公式,用一个数组记录然后统计答案就功德圆满了。基本毫无操作难度,就如同你与同学扯皮一般简单。下面是代码核心部分:
```cpp
int idx(char x)
{
return x-'0'+1;
}
int has(char x[])
{
int ans=0;
int len=strlen(x);
for(int i=0;i<len;i++)
{
ans=(ans*p+idx(x[i]))%mod+pri;
}
return ans;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
a[i]=has(x);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(a[i]!=a[i-1]) ans++;
}
cout<<ans<<endl;
return 0;
}
```

 

## 总结

这篇文章讲的只是哈希的一小小部分,当然加密强度更高的还有双哈希(基本冲突概率为零)。

蒟蒻第一次写博客,如有不完善的地方,请告知,我将仔细改正。

### 谢谢各位神犇的阅读!!!

posted @ 2022-09-10 09:48  finiinrdfz  阅读(81)  评论(0)    收藏  举报