日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

基本数据结构—Hash哈希

發(fā)布時(shí)間:2025/3/21 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基本数据结构—Hash哈希 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

理論概念

這玩意一直都是個(gè)好東西,但是我總覺(jué)得玄學(xué)的一批。今天借著專題學(xué)習(xí)的勁頭,把Hash好好梳理一下。

定義/作用

哈希這東西應(yīng)該都不陌生。將復(fù)雜的信息映射到一個(gè)容易維護(hù)的值域之內(nèi)。那么Hash函數(shù)就有點(diǎn)類似于一個(gè)映射關(guān)系。通過(guò)這個(gè)函數(shù)來(lái)產(chǎn)生一個(gè)關(guān)鍵值(Key),通過(guò)關(guān)鍵值與值(value)的對(duì)應(yīng)關(guān)系,制作一個(gè)對(duì)應(yīng)表。即哈希表(Hash table)。他可以實(shí)現(xiàn)通過(guò)Key快速的查找Value。

那么其最大作用也就顯而易見(jiàn)。查重。也就是說(shuō),查找當(dāng)前的值是否已經(jīng)存在。難點(diǎn)在于,如何去產(chǎn)生這個(gè)對(duì)應(yīng)關(guān)系?簡(jiǎn)單的映射關(guān)系是有相當(dāng)?shù)目赡墚a(chǎn)生“兩組不同的值生成同一個(gè)關(guān)鍵值”的錯(cuò)誤(我們稱其為哈希沖突)。如果哈希函數(shù)的設(shè)計(jì)太水,那么這個(gè)哈希沖突也就非常容易產(chǎn)生了。

整數(shù)(int)哈希舉例

引用了一個(gè)對(duì)整數(shù)數(shù)組生成Hash的方法,這里只做舉例。在本例中,不關(guān)心數(shù)組中數(shù)的序列問(wèn)題。即只考慮數(shù)組內(nèi)值不同為不同狀態(tài),如果值相同但順序不同,我們?nèi)哉J(rèn)為他是同一狀態(tài)。(會(huì)產(chǎn)生相同的關(guān)鍵值)

對(duì)于一組數(shù),其乘積與其累加之和與任意較大質(zhì)數(shù)P取模。

//這里是針對(duì)于某一個(gè)題目所引入的,所以具體原因會(huì)在下方的題目展示中闡釋。

字符串哈希

定義與技巧

常用的字符串哈希分兩類(沒(méi)錯(cuò),我覺(jué)得該分兩類的!)

自然溢出式Hash與多重Hash。一般來(lái)講,前者雖然發(fā)生哈希沖突的幾率非常小,但總會(huì)被刁鉆(誒嘿嘿)的出題人卡幾個(gè)數(shù)據(jù)。是的,他們是具備能卡你自然溢出單哈希的能力的。所以穩(wěn)妥起見(jiàn),后者運(yùn)用頻率偏高一些。

什么是字符串哈希?就是把一個(gè)任意長(zhǎng)度的字符串映射成一個(gè)非負(fù)整數(shù),并且其沖突概率幾乎為0

把字符串看作P進(jìn)制數(shù),并分配一個(gè)大于0的數(shù)值,代表每種字符。啥意思啊?比如a對(duì)應(yīng)1,b對(duì)應(yīng)2,c對(duì)應(yīng)3。取一個(gè)固定的值M,求出該P(yáng)進(jìn)制數(shù)對(duì)于M的余數(shù),作為該字符串的哈希值。一般來(lái)說(shuō),P取131或者13331,這樣沖突幾率就極低。一般M取264,也就是一個(gè)自然溢出的unsigned long long。就讓你溢出,取代低效的取模運(yùn)算。

這也就是第一類Hash。為了避免被卡,我們多取一些適當(dāng)?shù)腜與M。(例如大質(zhì)數(shù)),進(jìn)行多組Hash運(yùn)算。如果結(jié)果都相同,我們就認(rèn)定這是一個(gè)相等的字符串。

性質(zhì)

對(duì)沒(méi)錯(cuò)!我覺(jué)得這是性質(zhì)!!

有了以下兩種性質(zhì),我們便可以做到在O(N)的時(shí)間內(nèi)預(yù)處理所有前綴Hash值,并在O(1)的時(shí)間內(nèi)完成查詢?nèi)我庾执墓V怠?/p>

一、

對(duì)于任意新字符串S+C,他的Hash值就是

?H(S+C)=(H(S)*P+Value[C])mod M?

為什么?我們來(lái)進(jìn)行一個(gè)簡(jiǎn)單的模擬。

例如,S="abc",C=“d”

S表示為P進(jìn)制的數(shù):1 2 3

H(S)=1*P2+2*P+3

H(S+C)=1*P3+2*P2+3*P+4=H(S)*P+4

這里可以把*P的操作視為在P進(jìn)制下的左移運(yùn)算。Value[c]是我們?yōu)閏選定的代表數(shù)值。

二、

如果已知字符串S的Hash值為H(S),字符串S+T的Hash值為H(S+T),那么字符串T的Hash值

H(T)=(H(S+T)-H(S)*Plength(T)) mod M

那么我們繼續(xù)之前的模擬。

例如,S="abc",C=“d”,T=“xyz”

S表示為P進(jìn)制的數(shù):1 2 3

S+T的P進(jìn)制數(shù)為:1 2 3 24 25 26

H(S)=1*P2+2*P+3

H(S+T)=1*P5+2*P4+3*P3+24*P2+25*P+26

S在P進(jìn)制下左移length(T)位:1 2 3 0 0 0?

兩者相減就是T表示為P進(jìn)制數(shù):24 25 26

H(T)=H(S+T)-(1*P2+2*P+3)*P3=24*P2+25*P+26

在題目中的Show Time

Snowflake Snow Snowflakes? POJ3349

等待補(bǔ)充

兔子與兔子 CH1401

由于目標(biāo)題庫(kù)被查表…等待恢復(fù)。

好文章 2015模擬題By nodgd

因?yàn)檫@是一個(gè)專題博文,所以我不會(huì)去仔細(xì)深究他沒(méi)有涉及到哈希的原理。

在這道題中,我們可以枚舉每一個(gè)長(zhǎng)度為m的子串。那么一共會(huì)有n-m+1個(gè)長(zhǎng)度為m的子串。我們將他們的哈希值分別取出來(lái),然后再進(jìn)行比對(duì)。如果相等,則忽略,否則ans++

我聽(tīng)說(shuō)這道題用自然溢出哈希是翻車了的。故我貼這個(gè)題的目的,是想貼一下雙哈希的大概樣子。

#include<bits/stdc++.h> #define N 200009 using namespace std; char a[N]; long long ans, n, m,hs2[N], len1[N], len2[N], hs1[N],p1=131,p2=13331,mod1=1000000009,mod2=1000000007; struct hah{long long h1, h2; }hash[N]; long long cmp(hah x, hah y){if (x.h1 == y.h1) return x.h2 < y.h2; return x.h1 < y.h1; } void prepare(){len1[0] = 1, len2[0] = 1;for (int i = 1; i <= n; i++){hs2[i] = (hs2[i - 1] * p2 + (a[i] - 'a' + 1)) % mod2;//性質(zhì)1 hs1[i] = (hs1[i - 1] * p1 + (a[i] - 'a' + 1)) % mod1;len1[i] = (len1[i - 1] * p1) % mod1, len2[i] = (len2[i - 1] * p2) % mod2;//預(yù)處理了p的前綴和 次方 } } void gethash(long long l, long long r, long long oi){hash[oi].h2 = (hs1[r] - hs1[l - 1] * len1[r - l + 1] % mod1 + mod1) % mod1;//性質(zhì)2 hash[oi].h1 = (hs2[r] - hs2[l - 1] * len2[r - l + 1] % mod2 + mod2) % mod2; } int main(){cin>>n>>m;cin >> a + 1;prepare();for (int i = 1; i <= n - m + 1; i++)gethash(i, i + m - 1, i);//枚舉每個(gè)子串并取其哈希值 sort(hash + 1, hash + n - m + 2, cmp);for (int i = 1; i <= n - m + 1; i++)if (hash[i].h2 == hash[i + 1].h2 && hash[i].h1 == hash[i + 1].h1) continue;else ans++;cout<<ans; }

轉(zhuǎn)載于:https://www.cnblogs.com/Uninstalllingyi/p/11191045.html

總結(jié)

以上是生活随笔為你收集整理的基本数据结构—Hash哈希的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。