3.字串hash
4.一維子串的hash值
5.二維子串hash的值
雜湊就是把乙個元素通過一定的規則轉換為乙個整數,通過這個整數來表示這個元素。
舉例:
1.直接遍歷兩陣列,兩層for迴圈,複雜度o(nm)
缺點:複雜度太大
2.建立乙個陣列,用於提前處理,用下標當作a陣列的元素,值存為int型(出現次數)或者bool型,表示數存在不存在,直接遍歷a陣列即可。複雜度o(n+m)
缺點:陣列太大耗記憶體資源
上面兩種方法各有特點,也非常常用。可結合例子理解雜湊。
恒等變換:
h(key) = key
線性變換:
h(key) = a * key + b
把這個數平方,取中間的幾位當作hash值
h(key) = key % mod
但是可能會存在兩個數,使餘數相等,產生雜湊衝突。
雜湊衝突地解決辦法:
1.線性探查法
2.平方探查法
3.鏈位址法
這個可以用unordered_map實現。
上述方法不做闡述,如需了解,請自行搜尋相關部落格。
就是把乙個字串存成乙個數,用這個數來代表字串。
#include
using
namespace std;
string s;
//純小寫或純大寫 轉換為26進製
inthash_1()
//大小寫都有 轉換為52進製
inthash_2()
return h;
}int
main()
注意:運算都是從高位到低位。
公式:h[i] = (h[i-1]×26+index(str[i]))%mod
h[i] = (h[i-1]×p + index[str[i]])%mod
h[i…j] = (h[j]-h[i-1]×pj-i+1)%mod
但上述括號內可能取到負號:
需要再加乙個mod
h[i…j] = ((h[j]-h[i-1]×pj-i+1)%mod+mod)%mod
此時才算求出矩陣的hash值,而hash[i][j]表示(1,1)到(i,j)的二維矩陣hash值。
**:
for
(int i=
1;i<=n;i++
)for
(int j=
1;j<=m;j++
) has[i]
[j]=has[i]
[j-1
]*base1+a[i]
[j];
for(
int i=
1;i<=n;i++
)for
(int j=
1;j<=m;j++
) has[i]
[j]+
=has[i-1]
[j]*base2;
描述:子矩陣的右下角座標為(i,j),行數為n,列數為m。
子矩陣的hash值為:
hash[i][j] - hash[i-n][j] * base1n - hash[i][j-m] * base2m + hash[i-n][j-m] * base1n * base2m
可以發現這個與二位字首和非常像,可以根據字首和公式輔助記憶。
Hash 字串 字串雜湊
luo gu luogu luogup 3370 p3370 p337 0如題,給定n個字串 第i個字串長度為mi,字串內包含數字 大小寫字母 請求出n個字串中共有多少個不同的字串。第一行包含乙個整數n,為字串的個數。接下來n行每行包含乙個字串,為所提供的字串。輸出包含一行,包含乙個整數,為不同的字...
白兔的字串 字串hash
原題 一道典型的字串hash,至於hash,這裡講的非常好。一開始用map函式一直超時,後來改用unordered map就過了,至於這2個map的區別,這裡講的挺清楚的。之後去查了一下其它方法,發現還有一種方法是手寫map函式 強 指明 大佬 unordered map是跑了600ms,重寫跑了1...
字串 字串雜湊hash演算法
以洛谷p3370為引子引入吧 雜湊其實是所有字串操作中,筆者認為最簡單的操作了 except輸入輸出qwq 雜湊的過程,其實可以看作對乙個串的單向加密過程,並且需要保證所加的密不能高概率重複 就像不能讓隔壁老王輕易地用它家的鑰匙開啟你家門一樣qwq 通過這種方式來替代一些很費時間的操作。比如,最常見...