题目介绍
Hash详解
具体而言,你可以将hash理解为一个进制(奇怪的比喻
我们日常生活中常用的十进制是逢十进一。
比如,114514可以这样表示:
\[1 \times 10^5 + 1 \times 10^4 + 4 \times 10^3 + 5 \times 10^2 + 1 \times 10^1 + 4 \times 10^0\]十进制的底数为 $10$ ,也就是说 $base = 10$ 。相应地,二进制的 $base = 2$, 十六进制的 $base = 16$ 。
于是乎,一个以 $base$ 作为底数的进制可以写作:
\[a_i \times base^{i-1} + a_{i-1} \times base^{i-2} + \cdots + a_1 \times base^0\]好!非常好!CSP-J初赛内容你已经掌握了!
Hash就是对于字符串的每一位,找到对应的值。
我们以abcd为例:
$Hash(abcd)$
$=~’a’ \times base^3 + ~’b’ \times base^2 + ~’c’ \times base^1 + ~’d’ \times base^0$
其中, $base$ 是一个你自己定的值(推荐 $base$ 为质数,减少不同字符串却有相同 $base$ 值的可能)
Code
#include <bits/stdc++.h>
using namespace std;
/*数据类型选择 unsigned long long 自然溢出(虽然不是最好的方法)*/
const unsigned long long base = 131; //设置base
string a[10005];
set <unsigned long long> hsh;
//set 这个数据结构是自动去重的
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
unsigned long long tmp = 0;
for (int j = 0; j < a[i].length(); j++) {
tmp = tmp * base + a[i][j];
//找到字符串的哈希值
}
hsh.insert(tmp); //将这个哈希值存进 set
}
cout << hsh.size();
//set 的大小就是哈希值的数量,也就是不同字符串的数量
return 0;
}