從map到hash
阿新 • • 發佈:2018-06-08
存儲 減少 答案 class node 容易 自帶 span 相同 )復雜度飽受\(oier\)詬病。
我們可以棄置一定正確性,來換取時間復雜度降為\(O(1)\),這就是\(hash\)本質。
如何保證更高的正確性?這個問題沒有答案,因而很多\(hash\)方程都有其合理性。
一般在開始時,我們要選取一個\(Base\),原則是使\(Hash\)值分散,減少沖突。 )的方式盡可能避免沖突。
狀態量少時狀態可逆。
https://zybuluo.com/ysner/note/1175387
前言
這兩種技巧常用於記錄和去重量少而分散的狀態。
都體現了映射思想。
\(map\)
我一般是數組開不下時拿這玩意判重。
據說特別慢???
定義:
(註意一下比較規則必須顧及到所有變量,否則會重復)
struct node
{
int x,y;
bool operator < (node const &o) const {return (x<o.x)||(x==o.x&&y<o.y);}
}
map<node,int>Map;
判定是否重復:
if(map[(node){x,y}]) ;
於是因太弱而被\(xzy\)教育了一番
排序
\(map\)還有一種排序功能(類比\(Tire\)樹)。如果用\(map\)存字符串,那麽用以下方式就能按字典序遍歷所有字符串。
map<node,int>::iterator iter;
for(iter=Map.begin();iter!=Map.end();iter++)
{
string A=iter->first;
int B=iter->second;
...
}
據說還有一種叫\(unorder\_map\)的玩意兒,存儲時不排序,省時間,但我並不想管。。。
\(hash\)
\(map\)雖然能有效區分、避免重復,但其自帶的\(O(logn\)
我們可以棄置一定正確性,來換取時間復雜度降為\(O(1)\),這就是\(hash\)本質。
如何保證更高的正確性?這個問題沒有答案,因而很多\(hash\)方程都有其合理性。
一般在開始時,我們要選取一個\(Base\),原則是使\(Hash\)值分散,減少沖突。
字符串\(hash\)
通常將字符串看成一個進制數,比如\(ABAF\)看成\(1216\),
那麽哈希值就是
\[Hash[x]=1*Base^3+2*Base^2+1*Base+6\]
\(Base\)值自定,如果態量有限,可以使用較小的\(base\)使得所有狀態不沖突,若狀態量較大且分散,可以采用多次取模(多\(hash\)
狀態量少時狀態可逆。
樹\(hash\)
這玩意專為樹的同構而生。
怎樣的兩顆樹能稱為同構樹?
即樹的深度相同、孩子、子樹大小相同,只有孩子順序不同。
\[Hash[x]=\sum_{異或和}(Hash[son_{1..k}]+Base1)*(sz[x]+Base2)+deep[x]*Base3\]
如果用異或和而不是\({\sum}\),就能使\(Hash\)過程可逆。但\(Hash\)值密集時容易沖突,改成累乘就好了。
數\(hash\)
用來處理狀態量大而分散的情況,沒有\(map\)保險。。。
方程自定。
從map到hash