簡體   English   中英

為什么std :: hash <int> 似乎是身份功能

[英]Why std::hash<int> seems to be identity function

#include <iostream>

int main() {
    std::hash<int> hash_f;
    std::cout << hash_f(0) << std::endl;
    std::cout << hash_f(1) << std::endl;
    std::cout << hash_f(2) << std::endl;
    std::cout << hash_f(3) << std::endl;
}

我用“g ++ main.cpp -std = c ++ 11”編譯,結果是:

0
1
2
3

為什么會這樣? 我不使用任何庫,我沒有專門的散列函數。

附錄:我想為int的unordered_set的unordered_set定義散列,其中集合的散列是其組件散列的總和,但如果它只是標識它並不酷,因為{2,4}的散列是相同的{1,5}的哈希值。 避免這種情況的最簡單方法可能是使用std :: hash double函數。

它似乎是它的身份,它允許作為其獨特的..來自cpp參考

實際的散列函數是依賴於實現的,除了上面指定的那些之外,不需要滿足任何其他質量標准。 值得注意的是,一些實現使用簡單(標識)散列函數將整數映射到自身。 換句話說,這些散列函數被設計為與無序關聯容器一起使用,但不是作為加密散列。 ....

哈希函數intint似乎是完全合理的,並且不清楚為什么你會對此感到驚訝。 執行任何進一步的計算將毫無意義。 事實上,這是該術語的每個意義上的完美哈希

請記住, std::hash應該(幾乎唯一地) 標識值,而不是加密它們。

只有當你想要散列大於散列本身的類型(例如, uint9999999_t )時,才需要做一些工作來將值“壓縮”為散列的大小。

其他答案很好地涵蓋了身份功能背后的基本原理。 要解決您的附錄:

我想將unordered_set的哈希值定義為其組件哈希值的總和,但如果只是身份識別它並不酷,因為{2,4}的哈希值與{1,5}的哈希值相同。 避免這種情況的最簡單方法可能是使用std :: hash函數。

如您所見,使用+運算符組合哈希並不是最好的主意。 為了更加健壯,您可以使用XOR( ^ )運算符,或者從所采用的方法中獲取靈感,例如通過boost::hash_combine此SO帖子中的詳細信息 ):

seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);

例如,對於兩個整數對(1,5 / 2,4)和一個0的seed ,這將是有效的

uint32_t seed = 0;
seed ^= 1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= 5 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// 3449077526

uint32_t seed = 0;
seed ^= 2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= 4 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// 3449077584

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM