單詞到雜湊表的唯一對映演算法

2021-06-19 20:55:09 字數 3063 閱讀 6071



《programming pearls

,程式設計珠璣》15。

雜湊表是一種資料結構。可用雜湊表中的元素唯一地指向另一種資料結構。如程式設計珠璣介紹的用雜湊表元素指向儲存了「單詞和單詞數」的結構體,單詞從輸入流(一篇文章,一本書)中得來。可以將每次從輸入流中讀到的資料儲存在棧和堆中

1:雜湊表和儲存資料的資料結構

如上圖,用雜湊表元素指向結構體的方便之處在於不管資料儲存在**,都可以通過雜湊表元素將其訪問到。雜湊表的存在是為了更好的管理儲存資料的資料結構。我們希望通過雜湊表能夠更好的訪問儲存資料的資料結構。如統計輸入流中的不同單詞,並統計每個單詞的數目。為了實現這個目標,涉及到兩個問題:

儲存輸入資料的資料結構可以是如下結構:

struct _wordword;

所以雜湊表就是此種資料型別:

struct _word *pword[size];

。size

的選取要合適,要大於輸入流的不同單詞數。

選堆作為儲存地:由於每個

word

的大小不一,輸入單詞的數目未知,為了給輸入資料分配適當的空間而避免使用棧空間不夠或太多,所以使用堆記憶體來儲存輸入流中的單詞會更好。每當讀取到乙個單詞的時候我們就為其分配乙個恰當的堆記憶體儲存它。如果使用棧來儲存資料,我們一般就直接引用變數名或者陣列名就能夠索引到資料。只是堆記憶體無名,只有通過指標來索引。

首先,在程式開始時將雜湊表中的每乙個元素初始化為

null

,避免使用野指標。

其次,每當讀入乙個單詞時,判斷是否為之前讀入過的單詞,若是新單詞則有分配堆空間的操作(

p   = malloc(sizeof(word)

,p->word   = malloc(sizeof(inputword))

,然後儲存單詞在

word

指向的堆中)。然後將

p的值賦給雜湊表中的某乙個元素。若非新單詞,則通過指向此單詞資料結構的雜湊表元素為此單詞計數。

為避免使用額外的代價實現以上功能,出現了對映。這裡的對映就是每當輸入乙個單詞時,可以根據單詞的特性唯一地對映到雜湊表中的乙個元素之上(標識每乙個雜湊表元素的是下標值),這就解決了以上提到的兩個問題。如此,若是輸入重複單詞時,會對映到雜湊表中相同的乙個元素之上,就能夠為單詞計數了。雜湊表元素的下標是數字,字串的字元是

ascii

,可以由這裡出發讓單詞和雜湊表元素發生一一對應的關係。

其實,無論多長的乙個單詞,我們都可以將這個單詞看成是由

ascii

組成的,特殊的(分治思想)將其看成如下格式:

2:用分治法等效單詞的ascii值計算 1)

根據組成不同單詞的字元不同,可以直接根據每個單詞的

ascii

值來唯一的標識每個單詞。但不能保證不同的單詞其

ascii

就會不同。

」on」

和」on」

就是最好的例子。 2)

分析不同單詞擁有相同的

ascii

情況,只有下列三個等式中的其一成立時都可以得到不同單詞具有相同的

ascii值。

為了解決為不同單詞具有相同

ascii

的情況,為每個字元的ascii

值乘上乙個正整數

m^n(m> 1,

如字串」string」,i

對應的n值為4

,g對應的n

值為6)

,這就使得兩個單詞新的

ascii

值,單詞1的

ascii

值變為m^2 *ascii1  + m * ascii2

;單詞2

的ascii

值變為m^2 *ascii3  + m * ascii4

。這似乎就可以使得不同的單詞具有不同的

ascii

值。分析如下:

程式設計珠璣中是將每個字元擴大了

31倍,這可以保證每個單詞具有不同的標識值。筆記中的證明結果為:只要乘以乙個大於

1的正整數即可達到結果。

每個單詞的唯一整數標識問題解決了,假設根據以上計算能得到的每個單詞的新

ascii

值為newascii

。然後就是將每個單詞對映到雜湊表中的元素之上了。使用如下語句可以實現重複單詞的計數:

h   = newascii % size;   //size

為雜湊表的大小

pword[h]->word.count++;%使得

h的值在不同的

newascii

下可以得到

[0,size)

中的不同值。可見

程式中整數的除法。

最後,不能讓儲存堆位址的雜湊表元素值被覆蓋。需要雜湊表元素值操作儲存單詞的結構體,最好還要靠它釋放堆記憶體。

總結:對單詞的

ascii

值稍加運算為每個字元的ascii

值乘上乙個正整數

m^n(m > 1,

如字串」string」,i

對應的n值為4

,g對應的n

值為6)就解決了儲存每個單詞的資料結構與雜湊表元素的一一對應。

此次筆記記錄完畢。

LeetCode 288 單詞的唯一縮寫(雜湊)

乙個單詞的縮寫需要遵循 起始字母 中間字母數 結尾字母 這樣的格式。以下是一些單詞縮寫的範例 a it it 沒有縮寫 1 b d o g d1g 1111 5 0 5 8 c i nternationalizatio n i18n 11 5 0 d l ocalizatio n l10n假設你有乙...

拼寫單詞 仿造雜湊表的思想

給你乙份 詞彙表 字串陣列 words 和一張 字母表 字串 chars。假如你可以用 chars 中的 字母 字元 拼寫出 words 中的某個 單詞 字串 那麼我們就認為你掌握了這個單詞。注意 每次拼寫時,chars 中的每個字母都只能用一次。返回詞彙表 words 中你掌握的所有單詞的 長度之...

雜湊表有關的演算法

給定乙個整數陣列,判斷是否存在重複元素。如果任意一值在陣列 現至少兩次,函式返回 true 如果陣列中每個元素都不相同,則返回 false 示例1 輸入 1 2,3 1 輸出 true1.集合法,判斷原陣列和去重後的陣列是否相等 class solution def containsduplicat...