取一固定值p,把字串看作p進製數,並分配乙個大於0的數值,代表每種字元。一般般來說,我們分配的數值都遠小於p。例如,對於小寫字母構成的字串,可以令a = 1,b = 2, z = 26。取一固定值m,求出該p進製數對m的餘數,作為該字串的hash值。
字串hash函式把乙個任意長度的字串對映成一乙個非負整數,並且其衝突概率幾乎為零。
根據經驗,取p = 131或p = 13331,此時hash 值產生衝突的概率極低,只要hash值相同,我們就可以認為原字串是相等的。通常我們m=2^64,即直接使用unsigned long long型別儲存這個hash值,在計算時不處理算術溢位問題,產生溢位時相當於自動對2^64取模,這樣可以避免低效的取模(mod) 運算。
對字串的各種操作,都可以直接對p進製數進行算術運算反映到hash值上。如果我們已知字串s的hash 值為h(s), 那麼在s後新增乙個字元c構成的新字串s+c的hash值就是h(s +c) = (h(s)*p + value[c]) modm。其中乘p就相當於p進製下的左移運算,value[c] 是我們為c選定的代表數值。
如果我們已知字串s的hash值為h(s), 字串**s+t的hash值為h(s +t),那麼字串t的hash值h(t)= (h(s +t)- h(s)* plength(t) modm.**這就相當於通過p進製下在s後邊補0的方式,把s左移到與s+t的左端對齊,然後二者相減就得到了h(t)。
例如:
s= 「abc」, c= 「d」,t= 「xyz」,則:s表示為p進製數: 123
h(s)= 1p^2+2p+3
h(s+c)=1*p3 +2*p2 +3*p+4=h(s)*p+4
s+t表示為p進製數:123242526
h(s+t)=1*p5+2*p4+3*p3+24*p2+25*p+26
s在p進製下左移length(t) 位: 123000
二者相減就是t表示為p進製數: 24 2526
h(t)=h(s+t)-(1*p2 +2+p+3)*p3=24*p2 +25*p+26
根據上面兩種操作,我們可以通過0(n)的時間預處理字串所有字首hash值,並在0(1) 的時間內查詢它的任意子串的hash值。
題目大意:
很久很久以前,森林裡住著一群兔子。有一天,兔子們想要研究自己的dna序列。我們首先選取乙個好長好長的dna序列(小兔子是外星生物,dna序列可能包含26個小寫英文本母),然後我們每次選擇兩個區間,詢問如果用兩個區間裡的dna序列分別生產出來兩隻免子,這兩隻兔子是否一模一樣。注意兩隻兔子一模一樣只可能是它們的dna序列一模一樣。1 <= length(s),q <= 10^6。
思路:
記我們選取的dna序列為s,根據我們剛才提到的字串hash演算法,設f[i]表示字首子串s[1~i] 的hash值,有f[i=f[i-1]*131+(s[i]- 「a」+1).於是可以得到任一區間 [l.r] 的hash值為f[r] - f[i-1] * 131 - i + 1。當兩個區間的hash 值相同時,我們就認為對應的兩個子串相等。整個演算法的時間複雜度為o([s| + q)。
**:
#include
#include
#include
using
namespace std;
typedef
unsigned
long
long ull;
const
int n =
1000010
;char s[n]
;ull sum[n]
, p[n]
;int
main()
for(
int i =
1; i <= t; i++
)return0;
}
題目大意:
如果乙個字串正著讀和倒著讀是一樣的,則稱它是回文的。
給定乙個長度為n的字串s,求他的最長回文子串的長度是多少。
輸入樣例:
abcbabcbabcba
abacacbaaaab
end
輸出樣例:
case 1:13
case 2
:6
思路:
求出正序和逆序的hash值, 再遍歷每個點,以每個點為中心,二分查詢以它為中心的回文串的最大寬度。由於要分奇偶兩種情況討論,可以在字串的每兩個字元插入乙個不會用的的字元,將字元變為奇數。
列如:
abca#b#c
abcd
a#b#c#d
這樣就可以只討論奇數的情況。
**:
#include
#include
#include
using
namespace std;
const
int n =
2000010
, base =
131;
typedef
unsigned
long
long ull;
char s[n]
;ull hl[n]
, hr[n]
, p[n]
;ull get
(ull h,
int l,
int r)
intmain()
n *=2
; p[0]
=1;for
(int i =
1, j = n; i <= n; i++
, j--
)int res =0;
for(
int i =
1; i <= n; i++)if
(s[i - l]
<=
'z') res =
max(res, l +1)
;else res =
max(res, l);}
printf
("case %d: %d\n"
, c++
, res);}
return0;
}
資料結構 字串
1 字串 include string.h include stdio.h include stdlib.h include math.h include time.h define ok 1 define error 0 define true 1 define false 0 define ma...
資料結構 字串
字串是由0個或多個字元構成的序列,可記為s a1a2a3 an 其中ai可以是字母,也可是數字或者其他字元,零個字元的串稱為空串。而字串的順序結構就是用簡單的char型別陣列來儲存沒什麼好說的,下面介紹一下bf演算法與kmp演算法 bf演算法就是比較平常的雙重迴圈,如果匹配成功打斷迴圈,否則子串的比...
資料結構 字串
靜態陣列實現 順序儲存 串的順序儲存 define maxlen 255 預定義最大串長為255 typedef struct 靜態陣列實現 順序儲存 sstring 動態陣列實現 堆分配儲存 typedef struct 動態陣列實現 堆分配儲存 hstring 初始化void inithstri...