字串雜湊 模板

2021-08-30 19:29:10 字數 1597 閱讀 2472

以下文字**

據我的理解,hash就是乙個像函式一樣的東西,你放進去乙個值,它給你輸出來乙個值。輸出的值就是hash值。一般hash值會比原來的值更好儲存(更小)或比較。

那字串hash就非常好理解了。就是把字串轉換成乙個整數的函式。而且要盡量做到使字串對應唯一的hash值。

字串hash的種類還是有很多種的,不過在資訊學競賽中只會用到一種名為「bkdr hash」的字串hash演算法。

它的主要思路是選取恰當的進製,可以把字串中的字元看成乙個大數字中的每一位數字,不過比較字串和比較大數字的複雜度並沒有什麼區別(高精數的比較也是o(n)o(n)o(n)的),但只要把它對乙個數取模,然後認為取模後的結果相等原數就相等,那麼就可以在一定的錯誤率的基礎上o(1)o(1)o(1)進行判斷了。

那麼我們選擇什麼進製比較好?

首先不要把任意字元對應到數字0,比如假如把a對應到數字0,那麼將不能只從hash結果上區分ab和b(雖然可以額外判斷字串長度,但不把任意字元對應到數字0更加省事且沒有任何***),一般而言,把a-z對應到數字1-26比較合適。

關於進製的選擇實際上非常自由,大於所有字元對應的數字的最大值,不要含有模數的質因子(那還模什麼),比如乙個字符集是a到z的題目,選擇27、233、19260817都是可以的。

模數的選擇(盡量還是要選擇質數):

絕大多數情況下,不要選擇乙個10910^9109級別的數,因為這樣隨機資料都會有hash衝突,根據生日悖論,隨便找上109\sqrt109

​個串就有大概率出現至少一對hash 值相等的串(參見bzoj 3098 hash killer ii)。

最穩妥的辦法是選擇兩個10910^9109級別的質數,只有模這兩個數都相等才判斷相等,但常數略大,**相對難寫,目前暫時沒有辦法卡掉這種寫法(除了卡時間讓它超時)(參見bzoj 3099 hash killer iii)。

如果能背過或在考場上找出乙個101810^181018級別的質數(miller-rabin),也相對靠譜,主要用於前一種擔心會超時,後一種擔心被卡。

偷懶的寫法就是直接使用unsigned long long,不手動進行取模,它溢位時會自動對2642^64264進行取模,如果出題人比較良心,這種做法也不會被卡,但這個是完全可以卡的,卡的方法參見bzoj 3097 hash killer i。

**有待改進

#includeusing namespace std;

#define maxn 10005

#define inf 1e18

#define eps 0.00001

typedef long long ll;

const ll mod = 1e9+7;

const double pi = acos(-1);

ll n,ans = 1,arr[maxn];

ll hashs(string a)

return temp%mod;

}int main()

sort(arr+1,arr+1+n);

for(ll i = 2; i <= n; i++)

cout << ans << endl;

return 0;

}

模板 字串雜湊

如題,給定n個字串 第i個字串長度為mi,字串內包含數字 大小寫字母,大小寫敏感 請求出n個字串中共有多少個不同的字串。第一行包含乙個整數n,為字串的個數。接下來n行每行包含乙個字串,為所提供的字串。輸出包含一行,包含乙個整數,為不同的字串個數。s am plei nput sample input...

字串雜湊(模板)

尋找長度為n的主串s中的匹配串t 長度為m 出現的位置或次數屬於字串匹配問題。字串雜湊就是將每個字串轉化為乙個數值,然後遍歷主串,判斷在主串起始位置為i長度為m的字串的雜湊值與匹配串的雜湊值是否相等即可,每次判斷為o 1 的時間。這樣就可以轉化為o n 的時間完成判斷。若求字串中第i位到第j位的雜湊...

模板 字串雜湊

字串雜湊,說白了就是乙個函式,你把乙個字串輸入進去處理,輸出乙個更容易儲存或者比較的東西,相當於乙個加密的過程。但是對於同乙個加密方法,可能會有不同字串得到同樣的結果的情況,所以我們要做的就是讓字串的雜湊值盡量不相等。一般我們現在接觸到的字串雜湊,基本思想就是把它的每一位轉化成乙個特殊進製數的乙個數...