//hash
#include<bits/stdc++.h> #define f(i,j,n) for(int i=j;i<=n;i++) #define ll long long #define ull unsigned ll const int base=131; int prime=233317; ull mod=212370440130137957ll; int n; ull a[10010]; char s[10010]; using namespace std; void read(int &x) { int f=1; x=0; char s=getchar(); while(s<'0' or s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0' and s<='9') { x=x*10+s-'0'; s=getchar(); } x*=f; } ull hashe(char s[]) { int len=strlen(s); ull ans=0; for (int i=0; i<len; i++) ans=(ans*base+(ull)s[i])%mod+prime; return ans; } int main() { read(n); f(i,1,n) scanf("%s",&s),a[i]=hashe(s); sort(a+1,a+n+1); int ans=0; f(i,1,n-1) if(a[i]!=a[i+1]) ans++; printf("%d",ans+1); return 0; }
哈希實際上是全部字符串操做中,筆者認爲最簡單的操做了(except輸入輸出qwq)。哈希的過程,其實能夠看做對一個串的單向加密過程,而且須要保證所加的密不能高几率重複(就像不能讓隔壁老王輕易地用它家的鑰匙打開你家門同樣qwq),經過這種方式來替代一些很費時間的操做。html
好比,最多見的,固然就是經過哈希數組來判斷幾個串是否相同(洛谷P3370)。此處的操做呢,很簡單,就是對於每一個串,咱們經過一個固定的轉換方式,將相同的串使其的「密」必定相同,不一樣的串 儘可能 不一樣。c++
此處有人指出:那難道不能先比對字符串長度,而後比對ASCLL碼之和嗎?事實上顯然是不行的(好比ab和ba,並非同一個串,可是如是作卻會讓其認爲是qwq)。這種狀況就叫作hash衝突,而且在如此的單向加密哈希中,hash衝突的狀況在所不免(bzoj就有這種讓你給出一組樣例,使得一段哈希代碼衝突的題,讀者能夠嘗試嘗試)。數組
而咱們此處介紹的,便是最多見的一種哈希:進制哈希。進制哈希的核心即是給出一個固定進制base,將一個串的每個元素看作一個進制位上的數字,因此這個串就能夠看作一個base進制的數,那麼這個數就是這個串的哈希值;則咱們經過比對每一個串的的哈希值,便可判斷兩個串是否相同加密