题目描述
如题,给定 N N N 个字符串(第 i i i 个字符串长度为 M i M_i Mi ,字符串内包含数字、大小写字母,大小写敏感),请求出 NN 个字符串中共有多少个不同的字符串。
友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)
输入格式
第一行包含一个整数 N N N,为字符串的个数。
接下来 N N N 行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
输入
5
abc
aaaa
abc
abcc
12345
输出
4
我们先来看这个哈希常数 p p p最少是多少:26个小写字母(‘a’ ~ ‘z’),26个大写字母(‘A’ ~ ‘Z’),10个数字(‘0’~‘9’),加起来一共有62个字符。
但是保险起见,最好设一个稍微大一点的质数,比如137。
接下来我们把每一个字符串的哈希值算出来,找有没有重复的就行了。
#include <bits/stdc++.h>
using namespace std;
#define MAXN 10005
const int p = 137; //初始化哈希常数
char s[MAXN];
#define LL long long int
LL h[MAXN];
map<LL, LL> m; //这里的map是用来判断哈希值是不是重复的,如果重复了
LL gethash(char s[])
{
int len = strlen(s);
LL sum = 0;
for(int i = len - 1; i >= 0; i--)
sum = sum * p + s[i] - '0'; //哈希函数,我把一个字符串看作一137进制数处理了
return sum;
}
int main()
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%s", s);
h[i] = gethash(s);
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(!m[h[i]])
{
m[h[i]] = 1; //判断哈希值是否重复,其实双哈希最保险,但是我写的单哈希
ans++;
}
}
cout << ans << endl;
return 0;
}