其实也并不是什么特别难的算法,但是我个人实在是不太喜欢字符串之类的东西(字符串神马的真的是麻烦),于是一直拖着不想看,然后模板题之类的也懒得做。
Hash的思想其实也没什么复杂的,就是给定一系列字符串以后,根据字符串的特点(长度、只有数字、只有小写字母、只有大写字母等等)选择一个适当的值,将所有的字符串转化为数值存储在数组里。当然还要注意解决冲突,在数据特别大的情况下,很难保证不会出现不同字符串Hash值相同的情况。解决冲突的方法也有很多,这里我就不多说了,我自己也并不是对所有方法都熟悉,自己去看看别的大犇的博客吧(其实是我懒_(:з」∠)_)
关于Hash,我理解的也并没有多深,更加专业,更加深入,更加NB,更加有B格的解释还是去看看大犇们的解释吧。
这里我再放下洛谷的模板题的代码,题目传送门
#include<bits/stdc++.h> #define mod 1000007 using namespace std; typedef unsigned long long ull; const int N=1e4+7; int n,vis[1000010],ans; ull hash,id[N][1507]; char s[1507]; inline bool check(int x,int y) { if( id[x][0]!=id[y][0] ) return false; for(int i=1; i<id[x][0]; ++i) if( id[x][i]!=id[y][i] ) return false; return true; } int main() { scanf("%d",&n); for(int i=1; i<=n; ++i) { scanf("%s",s); id[i][0]=strlen(s); hash=1; for(int j=0; j<id[i][0]; ++j) { hash=(hash*s[j]*31)%mod; id[i][j+1]=hash; } while( vis[hash] ) { if( check(vis[hash],i) ) break; hash++; } if( !vis[hash] ) { vis[hash]=i; ans++; } } return printf("%d ",ans),0; }