C 字串的 hash 值計算

2021-09-26 09:35:31 字數 2125 閱讀 2789

c++ 11 中新加入的容器 unordered_map 和 unordered_set 底層都是雜湊表實現的,那麼對於內建型別,肯定是可以自動計算出 hash 值的,但是對於像 pair或者 vector這樣的,或者自定義的類這種複雜型別,就不能自動算出 hash 值了,編譯會提示the c++ standard doesn』t provide a hash for this type。那麼就需要自己去定義 hash function 了,自定義 hash 函式可以參考 這裡不討論這個問題。

本文學習並記錄一下 c++ 中 string 的 hash 計算方式。首先我們定義乙個 unordered_map 如unordered_seths;,然後跳到 unordered_map 的定義,可以看到模板引數中第二個引數就是 hash 函式,預設使用 hash<_kty>

然後再跳到 hash<_kty> 的定義,如下,有乙個模板實現,以及一些模板特化,但是沒有針對 string 的特化。

再跳過去,這裡有提示"only trivial types can be directly hashed."

就是這裡了!!這裡的返回值就是 hash 值,這個函式也很簡單,就是從前到後遍歷這個傳入的引數,對每一位,先轉換為 size_t,然後和 _val 進行異或(注意 _val 傳入就是_fnv_offset_basis),然後_val *= _fnv_prime;。也就是傳入的是 string 的話,對每個字元,轉換成 size_t(應該就是 ascii 碼),異或,乘乙個常量,迴圈。重點就是下邊這兩句

_val ^

=static_cast

(_first[_idx]);

_val *

= _fnv_prime;

下面我們驗證一下。

#include

#include

using

namespace std;

constexpr size_t tmp_fnv_offset_basis =

2166136261u

;constexpr size_t tmp_fnv_prime =

16777619u

;int

main()

cout <<

"val2 = "

<< val2 << endl;

}

結果如下:

hash()(『a』) = 3826002220

hash()(「a」) = 3826002220

hash()(「abc」) = 440920331

val1 = 3826002220

val2 = 440920331

說明 string 的 hash 值確實是這麼計算的,字元也是這麼處理,就相當於是長度為 1 的字串。

不過《stl原始碼剖析》裡講,sgi stl 中,string 是按照如下方式計算的:

// 以下定義於 

template

<

class

key>

struct hash

;inline size_t __stl_hash_string

(const

char

* s)

白兔的字串 字串hash

原題 一道典型的字串hash,至於hash,這裡講的非常好。一開始用map函式一直超時,後來改用unordered map就過了,至於這2個map的區別,這裡講的挺清楚的。之後去查了一下其它方法,發現還有一種方法是手寫map函式 強 指明 大佬 unordered map是跑了600ms,重寫跑了1...

Hash 字串 字串雜湊

luo gu luogu luogup 3370 p3370 p337 0如題,給定n個字串 第i個字串長度為mi,字串內包含數字 大小寫字母 請求出n個字串中共有多少個不同的字串。第一行包含乙個整數n,為字串的個數。接下來n行每行包含乙個字串,為所提供的字串。輸出包含一行,包含乙個整數,為不同的字...

字串 字串雜湊hash演算法

以洛谷p3370為引子引入吧 雜湊其實是所有字串操作中,筆者認為最簡單的操作了 except輸入輸出qwq 雜湊的過程,其實可以看作對乙個串的單向加密過程,並且需要保證所加的密不能高概率重複 就像不能讓隔壁老王輕易地用它家的鑰匙開啟你家門一樣qwq 通過這種方式來替代一些很費時間的操作。比如,最常見...