字串hash函式把乙個任意長度的字串對映成乙個非負整數,並且其衝突概率幾乎為0;
字串hash函式:取一固定值p,把字串看做p進製數,並分配乙個大於零的的數值,代表每種字元,取一固定值m,求出該p進製對m的餘數,作為該字元的hash值
一般來說,我們取p=131或p=13331,此時hash值產生衝突的概率極低,只要hash值相同我們就可以以為原字元就是相等的。
·我們還可以多取一些恰當的p的m的值(列如大質數),多進行機組hash運算,當結果都相同時才認為原字元相等
對字元地的各種操作,都可以直接對p進製數進行算術運算反映到hash值上。
列如:s=「abc」,c=「d」,t=「xyz」;則:
s表示為p進製數:1 2 3
h(s)=1p^2+2p+3;
h(s)=1p3+2*p2+3p+4;
s+t表示為p進製數:1 2 3 24 25 26
h(s+t)=1p5+2*p4+3p3+24*p2+25p^+26
s在p進製下左移length(t)位:1 2 3 0 0 0
二者相減就是t表示為p進製數:24 25 26
h(t)=h(s+t)-(1p2+2*p+3)*p3=24*p2+25*p+26;
例題;很久很久以前,森林裡住著一群兔子。
有一天,兔子們想要研究自己的 dna 序列。
我們首先選取乙個好長好長的 dna 序列(小兔子是外星生物,dna 序列可能包含 26 個小寫英文本母)。
然後我們每次選擇兩個區間,詢問如果用兩個區間裡的 dna 序列分別生產出來兩隻兔子,這兩個兔子是否一模一樣。
注意兩個兔子一模一樣只可能是他們的 dna 序列一模一樣。
輸入格式
第一行輸入乙個 dna 字串 s。
第二行乙個數字 m,表示 m 次詢問。
接下來 m 行,每行四個數字 l1,r1,l2,r2l1,r1,l2,r2,分別表示此次詢問的兩個區間,注意字串的位置從1開始編號。
輸出格式
對於每次詢問,輸出一行表示結果。
如果兩隻兔子完全相同輸出 yes,否則輸出 no(注意大小寫)。
資料範圍
1≤length(s),m≤10000001≤length(s),m≤1000000
輸入樣例:
aabbaabb
31 3 5 7
1 3 6 8
1 2 1 2
輸出樣例:
yesno
yes**;
#include#include#include#includeusing namespace std;
const int maxn=1e6+5;
char s[maxn];
unsigned long long f[10000001],p[1000001];
int main()
cin>>m;
for(int i=1;i<=m;i++)
{int l1,l2,r1,r2;
cin>>l1>>r1>>l2>>r2;
if(f[r1]-f[l1-1]*p[r1-l1+1]==f[r2]-f[l2-1]*p[r2-l2+1])
cout<<"yes"《事先處理p的n次方是個不錯的想法,之前沒用過;可以先定義p與m,這裡直接用預設值了。
字串HASH函式
常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用 位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rs...
字串經典hash函式
常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用 位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rs...
字串經典hash函式
常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用 位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rs...