哈希算法
哈希算法是一种字符串算法,哈希本质来说有很多种,但是算法竞赛中往往只涉及一种即将一个字符串记作一个k进制的数,保证每个长度,每种内容的字符串都有在k进制下的唯一表达方式,哈希算法本身是为字符串提供了一个简记的方式,这种方式往往可以使字符串的比较更加便捷快速,我们也可以将哈希看作一个函数,我们将一个字符串输入进函数中,然后返回的值就是这个字符串的另一种(唯一的)表达方式。
下面我们详细介绍哈希算法。
哈希算法一般包括下面几个步骤:1.定进制(即设置一个进制k,保证k可以涵盖每个可能出现的字符且值不重复)2.取模数(保证取模后不会发生冲突)
而哈希对字符串的值的计算的方式一般是以递推的方式实现的,比如一个字符串 ‘asdasdac’ 这个字符串是由小写字母组成的,我们的模数就可以取27,将这个字符串看成一个27进制的数,我们先读入第一个字符 'a' 我们定义一个计数变量来记录字符串的值:sum ,我们读入第一个字符后,sum=sum*27+'a';接着,我们继续读入第二个字符:'s' 我们的sum=sum*27+'c' 这时,我们里面存贮的值是 'a'*27+'c' 这恰好是一个两位的27进制数,每一位乘上这一位的权值。我们递推下去就可以得到这个字符串的哈希值,我们在比较两个字符串是否相等的时候就可以直接比较这两个字符串的哈希值是否相等,如果相等那么这两个字符串一定相等。
下面我放一道哈希入门题
题目描述
如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。
#友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)
输入格式
第一行包含一个整数N,为字符串的个数。
接下来N行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
5 abc aaaa abc abcc 12345
4
说明/提示
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,Mi≈6,Mmax<=15;
对于70%的数据:N<=1000,Mi≈100,Mmax<=150
对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500
样例说明:
样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。
##题目来自洛谷,题目作者HansBug
我们看这一道题,我们只用求出每个字符串的值,然后sort排序,判断每一个hash值和后一个hash值是否相等,如果不相等,答案加一。
下面上代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define unlolo unsigned long long using namespace std; unlolo a[50000],n; char d[50000]; unlolo b=131,l; bool cmp(int x,int y){ return x<y; } unlolo hash(char s[]){ unlolo ans=0; for(int i=0;i<strlen(s)-1;i++){ ans=ans*b+(unlolo)s[i]; } return ans; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>d; a[i]=hash(d); } sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++){ if(a[i]!=a[i+1]) l++; } cout<<l; }
谢谢阅读。