题目描述
如题,给定 N 个字符串(第 i 个字符串长度为 Mi,字符串内包含数字、大小写字母,大小写敏感),请求出 N 个字符串中共有多少个不同的字符串。
输入格式
第一行包含一个整数 N,为字符串的个数。
接下来 N 行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
5
abc
aaaa
abc
abcc
12345
4
对于这道题的总结如下:
首先字符串哈希得明白它就是把不同的字符串映射成不同的整数,然后如下:
1.把字符串映射成一个p进制数字,对于一个长度为n的字符串s,我们可以这样定义它的hash函数
,你也可以定义自己的hash函数。
2.但是如果碰到两字符串不一样,但hash值却一样,怎么办呢?
3.所以我们要设置p和M的值,保证p与M互质
所以p通常取131或13331
M我们就定义成unsigned 就行,刚好省去自己去模。因为无符号整形超过会自动溢出,等价于取模。
下面是我的ac代码:
#include<bits/stdc++.h>
using namespace std;
using ULL = unsigned long long;
int n;
const int N = 1e4 + 10;
const int p = 131;
ULL h[N], ans[N];
char ch[N];
ULL init(char* s, int len) {
h[0] = 0;
for (int i = 1; i <= len; i++) {
h[i] = h[i - 1] * p+s[i];
}
return h[len];
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
scanf("%s", ch + 1);
int len = strlen(ch + 1);
ans[i] = init(ch, len);
}
sort(ans + 1, ans + 1 + n);
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (ans[i] != ans[i - 1])cnt++;
}
cout << cnt << endl;
return 0;
}