【模板】字符串哈希
题目描述
如题,给定 N N N 个字符串(第 i i i 个字符串长度为 M i M_i Mi,字符串内包含数字、大小写字母,大小写敏感),请求出 N N N 个字符串中共有多少个不同的字符串。
友情提醒:如果真的想好好练习哈希的话,请自觉。
输入格式
第一行包含一个整数 N N N,为字符串的个数。
接下来 N N N 行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
样例 #1
样例输入 #1
5
abc
aaaa
abc
abcc
12345
样例输出 #1
4
提示
对于 30 % 30\% 30% 的数据: N ≤ 10 N\leq 10 N≤10, M i ≈ 6 M_i≈6 Mi≈6, M m a x ≤ 15 Mmax\leq 15 Mmax≤15。
对于 70 % 70\% 70% 的数据: N ≤ 1000 N\leq 1000 N≤1000, M i ≈ 100 M_i≈100 Mi≈100, M m a x ≤ 150 Mmax\leq 150 Mmax≤150。
对于 100 % 100\% 100% 的数据: N ≤ 10000 N\leq 10000 N≤10000, M i ≈ 1000 M_i≈1000 Mi≈1000, M m a x ≤ 1500 Mmax\leq 1500 Mmax≤1500。
样例说明:
样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。
题解
首先呢,哈希算法个人理解就是一种加密方式,我们需要产生一个尽可能不会重复的信息来代替原来的对象。
所以呢这道字符串哈希我们就需要讲每个字符串通过哈希来变成一串数字,并且去重输出就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
//这种方式是不自觉的方式,直接用set自动去重,输出。
//但是这不是我们所需要的
void fun1(){
set<string> a;
int n;
cin>>n;
for(int i=0;i<n;i++){
string s;
cin>>s;
a.insert(s);
}
cout<<a.size()<<endl;
}
// ull fun3(){
// ull a=0xffffffffffffffff;
// a=a/131-131;
// int flag=0;
// while(1){
// for(int i=2;i<=sqrt(a);i++){
// if(a%i==0){
// flag=1;
// break;
// }
// }
// if(flag==0){
// return a;
// }
// a--;
// }
// }
// ull Stringhash(string s){
// ull code=0,x=131,y=140814840257324663;
// for(int i=0;i<s.size();i++){
// code=(code*x+(ull)s[i])%y;
// }
// return code;
// }
//code代表编码,x只要是一个比较大的质数就可以 131,161,611都是可以的
//让字符串的每一位数乘一个编码,通过这种方式就可以产生不同的数字代表字符串
ull Stringhash(string s){
ull code=0,x=131;
for(int i=0;i<s.size();i++){
code=code*x+(ull)s[i];
}
return code;
}
void fun2(){
int n;
cin>>n;
string s;
ull a[10005];
for(int i=0;i<n;i++){
cin>>s;
a[i]=Stringhash(s);
}
sort(a,a+n);
ull ans;
ans=unique(a,a+n)-a;
//unique的作用是“去掉”容器中相邻元素的重复元素,所以需要先排序,并且它返回的是一个地址。
cout<<ans<<endl;
}
int main(){
fun2();
return 0;
}