字串雜湊表

2021-10-25 10:55:16 字數 3609 閱讀 5709

主要目的是實現基於字典的字串壓縮時,快速的判斷乙個詞是否出現在字典中並獲取其編碼。

這種方法速度挺快,而且方便檔案讀寫,節約記憶體空間,主要是有趣。

#pragma once

/** 1.如果使用合理的雜湊演算法,若雜湊值可以有無限位,那麼某些雜湊演算法得到的雜湊值不可能相同,

* 自然溢位得到的32位雜湊值相同的概率也是很小的,除留餘數法取位址後衝突率大大增加,所以除數的選取至關重要。

* * 2.此處使用額外的兩個雜湊值校驗,不進行字串鍵的比較,所以當雜湊表只是用來查詢值或者

* 判斷鍵的存在性時,不需要儲存字串本身,但是為了擴容時的重定位,需要儲存用於定址的那個雜湊值。

* * 3.需要至少兩個雜湊值來校驗用以保證正確性,既然需要儲存用於定址的那個雜湊值(未除留餘數前的),

* 又知道衝突主要來自於除留餘數之後,那麼這個雜湊值仍然具有校驗價值,所以只需要額外計算乙個

* 校驗雜湊值即可,但是需要使用完全無關聯的雜湊演算法計算兩個雜湊值,可能安全性不如計算三個雜湊值好,

* 但是測試了許多的資料沒有出現錯誤的情況。

* * 4.採用線性探測法來處理衝突,那麼當表長較小時,由於衝突的疊加勢必會有較多的衝突,所以表的裝填因子不宜

* 過大(要小於等於0.5比較好),也就是會有較多的空間浪費,所以適合於資料量不是太大的情況。

* * 5.對於開放定址處理衝突的方法,不能輕易刪除某個鍵,因為可能會阻斷其他鍵的查詢路徑(可以定期維護,

* 但是麻煩),所以不適合有刪除鍵操作的情況。

* * 6.根據線性探測法衝突疊加的性質可知,後來插入的鍵衝突概率會增大,如果已知大部分待查詢的鍵都可以查詢成功,

* 那麼就可以按查詢頻率插入鍵來減少平均查詢長度,但是對於查詢失敗的鍵不管用。

* * 7.使用類似hashmap的表長(2^n)及動態擴容方法及(key & (tablelength - 1))的取址方法會比較簡潔,但是實驗的資料

* 雜湊的不如素數表長好。

*/#ifdef _debug

#include

#endif

typedef

unsigned

int uint;

static

const uint alterlength=

;#define max_table_length 359339171u

/* 若鍵個數大於最大表長則仍會使用最大表長,此時插入會死迴圈,但是一般是不太大的資料量使用,故沒有再檢查。 */

template

class stringhashtable

}hash_node,

* hash_table;

/* 規範化表長 */

uint normtablelength

(uint tablelength)

;/* 暴雪的那個雜湊函式不明白,用了簡單的字串雜湊函式 */

void

hash

(char

* str, uint strlength, uint& key, uint& check)

;/* 擴容時的插入函式 */

void

insert

(hash_node& hashnode)

;/* 嘗試擴容 */

void

tryexpandtable()

;private:

hash_table table;

// 雜湊表

uint tablelength;

// 雜湊表長

uint usedindexcounts;

// 占用位置計數

uint lengthindex;

// 表長在候選表中的索引

valuetype badvalue;

// 初始時使用此值填充表,並用以判斷位置是否空閒};

template

inline stringhashtable::

stringhashtable

(valuetype badvalue)

template

inline stringhashtable::

stringhashtable

(valuetype badvalue, uint inittablelength)

template

inline stringhashtable::

~stringhashtable()

}template

inline uint stringhashtable::

_tablelength()

template

inline uint stringhashtable::

_usedindexcounts()

template

inline

void stringhashtable::

insert

(char

* str, uint strlength, valuetype value)

#ifdef _debug

std:

:cout << conflict << std:

:endl;

#endif

table[addr]

.key = key;

table[addr]

.check = check;

table[addr]

.value = value;

usedindexcounts++

;tryexpandtable()

;}template

inline valuetype stringhashtable::

getvalue

(char

* str, uint strlength)

return table[addr]

.value;

}template

inline uint stringhashtable::

normtablelength

(uint tablelength)

}template

inline

void stringhashtable::

hash

(char

* str, uint strlength, uint& key, uint& check)

//key ^= (key >> 16); // 高低位擾動

}template

inline

void stringhashtable::

insert

(hash_node& hashnode)

table[addr]

= hashnode;

}#define max_loadfactor 0.5f

template

inline

void stringhashtable::

tryexpandtable()

delete[

] temptable;

}

16 字串雜湊 雜湊表

這個方法叫做字串字首雜湊法 先求出來每個字首的雜湊值 問題1 如何來定義某乙個字首的雜湊值 把這個字串看成是乙個p進製的數 每一位上的字母的ascii碼,就是這一位上的數 最後mod上乙個很小的數,就對映到0 q 1 這樣就可以把乙個字串轉換為乙個數字 注意事項1 一般情況下,不能把某個字母對映成0...

字串雜湊

參照演算法筆記p109,甲級1039 先假設字串均由大寫字母a z構成。在這個基礎上,不妨把a z視為0 25,這樣就把26個大寫字母對應到了26進製中。接著,按照將26進製轉化為10進製的思路,由進製的轉換結論可知,在進製轉換過程中,得到的10進製肯定是唯一的,由此便可實現將字串對映為整數的需求 ...

字串雜湊

昨天做了一道字串雜湊的題,感覺還好理解。今天的題看了 不知道為什麼,搜來搜去發現不知道的東西還很多,網上找到的東西也都是很零散,書上也沒有系統的講解。先自己整理一下這些零散的知識 關於字串涉及到的演算法大概有 hash kmp trie ac自動機等等,現在還都不明白是怎麼回事,這次先研究字串has...