文本处理简介:让我们在 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 分钟来处理。
现在,让我们考虑使用这个双精度数组作为最后的点睛之笔进行搜索。