文字處理簡介:讓我們在 Python 中快速製作字典(第 3 部分)

目錄
[第 1 部分]
[第 2 部分]
[第 3 部分]
[第 4 部分]
雙精度陣列的 Python 實現(第 1 部分)
上面的解釋是一個 Python 程式。
(如果您開始閱讀此處並對內容感到好奇,請回去輕鬆閱讀。
我會先寫下政策和注意事項。
“處理每個階段”
雙精度陣列的創建稱為 “transition from one node to the next node”
它可以分解為方面的處理。
我們全方位都是這樣做的。
如果你考慮處理一個方面需要什麼樣的輸入,
“對於詞頭之前的任何字串(包括空字串和詞頭本身),
下一組字元(包括單詞的結尾)首先是必需的。
子字串由字元ID元組表示,下一個字元由一組字元ID表示並存儲在 dict 中。
在本文中,我們將它稱為 「分支資料庫」。
另一個是它當時過渡的節點的位置。
換句話說,節點從子字串的開頭過渡到結尾時的位置。
同樣,子字串的字元ID的元組是鍵,而轉換到它時的節點位置是值。
dict(defaultdict) 的 在本文中,我們將它稱為 「過渡源資料庫」。
讓我們提前創建分支資料庫。
在創建 double 陣列時添加源資料庫中的項。
此外,當項目對應的 aspect 的計算完成後,請將其刪除,因為它不再使用。
“優點和注意事項”
現在,「每個階段處理,所有階段重複」的計算方法有兩個優點。
首先,您不必使用遞歸。
我覺得使用遞歸更容易實現,但我小心翼翼地不要太深入。
在運行時之前,可能很難考慮它。
另一方面,如果嘗試在沒有遞歸的迴圈中寫入,則演算法通常會更複雜。
這次我也嘗試在一個迴圈中編寫它,但我已經將過程分解為多個階段,所以
在那之後,這很容易,因為很容易對相位數進行簡單的迴圈。
另一個優點是計算順序(例如廣度優先或深度優先)與程式的設計無關。
如果更改輸入數據(分支資料庫中的專案)的檢索順序,則可以回應其中任何一個。
它可以通過任何一種方法進行計算。 (這一次,優先考慮深度)
它充滿了美好的事物,但也有一些警告。 它說,「在計算過渡時,
轉換前的計算必須已經完成。
這是因為源資料庫在那一刻需要源節點位置。
在準備分支資料庫時,請記住這一點。
雙精度陣列的 Python 實現(第 2 部分)
編寫一個程式,然後開始。 首先,我們準備輸入數據(headwords 清單)。
標題可以是到目前為止的解釋中熟悉的六個詞,「den」和「where」......
正如我在開頭所寫的,我將使用日文版維琪百科的標題清單。
幾乎所有字元都將單獨包含在標題中,因此請使用包含兩個或多個字母的標題。
在撰寫本文時(2018 年 10 月),大約有 180 萬台。 這是一個完美的數量。
將其保存回 words.txt。 headword 的單詞 ID 應為行號。
(如果它是一個實際的字典,它將是語義數據的記錄數量,等等。
放加工。 要下載標題,我們將向您展示連結,因此請手動進行。
現在,我們編寫創建 double 數位列所需的函數。
功能:get_branch_db
首先,準備分支資料庫的函數。 再
“Substring from the beginning” = > “the next character” 在字典中註冊。
順便說一句,我還將執行為角色分配ID的過程。 此外,請確保滿足上述說明中描述的順序。
順便說一句,我想在這個過程中使用 defaultdict 並仍然保持密鑰的註冊順序。
Python 的某些版本和實現不保證此行為。
創建這樣的 dict 作為新類會很好,但現在簡單而天真的解決方案是使用
讓我們獨立於 dict 創建一個 key 陣列。
功能:get_base_s
創建一個函數,以便在從位置 s 轉換時尋找底數。
從分支字元的字元ID數位的每個元素創建一個偏移量陣列,減去最小的字元ID。
找到一個位置,使 offsets 陣列的每個元素都盡可能靠近未使用區域的左側。
如果你從那裡向後工作,你可以找到base[s]。
功能:update_slot_start
與上述相關,在尋找空缺以決定過渡目的地時,如果您每次都在尋找路線,
隨著節點數量的增加,它變得越來越慢。
由於 double 陣列的空位是(應該)從左側填充的,因此創建一個函數來查找空位的左端。
讓我們相應地稱呼它。
功能:make_darray
這是一個用於創建雙精度陣列 (base, check) 的函數。 該函數的輸入是一個分支資料庫。
讓我們用類似偽代碼的句子編寫演算法。
__Empty源資料庫 (substring)=>節點位置)
從分支資料庫(迴圈)中__Retrieving一對 “substrings and the character set of the transition destination”
____Update自由位置的左邊緣(update_slot_start)
______ 初始計算(從路線過渡):
________ Transition Source (過渡源)s = 1
處理________過渡(省略,因為以下內容和基礎知識相同)
________ 在轉移源資料庫中註冊轉移目標的位置
______否則:
________s的值是從源資料庫獲取的
當________葉節點且未分支時:
__________基地標題身份證轉換為負數
其他時間________:
__________ 從過渡目標的字元集中檢索一個字元(迴圈)
____________基地尋求(get_base_s)
____________ 過渡目標t = 基數 + c
____________檢查[t] = s
____________ 如果目標是葉節點:
______________基地[t]標題身份證轉換為負數
以外____________:
______________ 在過渡源資料庫中註冊過渡目標的位置。
已計算________的專案將從過渡源資料庫中刪除。
功能:save_darray
將創建的 double 陣列寫入檔案。
目前,請為陣列的每個元素留出 3 個字節。
(本來這樣的決定並不好,所以我們來計算一下吧! )
有一些有用的函數可以在不使用 pack 或 unpack 的情況下處理二進位檔,因此我將把它留給它們。
此外,字元和字元ID之間的對應表以字串的形式輸出到文字檔中。
最後,對上述處理的調用在main函數中進行了總結。
這是代碼。
darray 的 你得到 {base,check,code} 這三個檔了嗎?
創建了大約 770 萬個節點。
如果 CPU 是 Core i7 且記憶體為 8GB,則需要 1~2 分鐘來處理。
現在,讓我們考慮使用這個雙精度陣列作為最後的點睛之筆進行搜索。