我用一个双数组实现了Trie。
前回のブログで、辞書検索、サジェスト、形態素解析などを実装するのに使われるTrieの概略を紹介しました。
在我们之前的博客中,我们概述了Trie,它是用来实现字典搜索、建议和形态分析的。
木構造の各エッジに文字のラベルを付けることで辞書を表現するという抽象的な説明を与え、それを実現するLOUDSという簡潔データ構造を紹介しました。 今回はLOUDSとは別の、Double Array(ダブル配列)というデータ構造で実際にTrieをPythonで構築し、共通接頭辞検索を行えるようにします。 実装方法については 『日本語入力を支える技術』(徳永, 2012)、通称「徳永本」に準拠しますので、同著を読まれた方が実装を試みる際の参考にもなると思います。 また、Double arrayのエッセンスを紹介していきますので、参考書籍をお持ちでない方もDouble arrayによるTrieの実装について理解できることを目指しています。
我们给出了一个抽象的描述,即通过用字母标记树状结构的每条边来代表一个字典,并介绍了一个简洁的数据结构,称为LOUDS,以实现这一目的。 这一次,我们将在Python中实际建立Trie,使用一种叫做Double Array的数据结构,这与LOUDS不同,以实现常见的前缀搜索。 该实施方法基于 《日语输入法背后的技术》(Tokunaga, 2012),通常被称为Tokunaga书,因此该书的读者在尝试实施时可能会发现它很有用。 还将介绍双数组的本质,这样,那些没有参考书的人就能理解用双数组实现Trie。
前提:Trieを実装する上で、データ構造の選択は重要
假设:数据结构的选择对于实现Trie很重要。
まず、Trieを実装する際のデータ構造として、LOUDSやDouble Arrayといった様々な選択肢が存在する背景を紹介しておきます。 検索の高速性を担保しつつTrieを実装する素朴な方法として、各ノードからの文字ごとの遷移先をテーブルに格納しておくというやり方が挙げられます。
首先,对实现Trie的各种数据结构选项,如LOUDS和Double Arrays,给出一些背景。 在保证高搜索速度的同时,实现Trie的一个天真的方法是将每个节点的逐个字符转换存储在一个表中。
このようなTrieを想定してみましょう(ノードの番号は幅優先で付与)。
假设有这样一个Trie(节点编号有宽度优先权)。
上記のTrieに対応するテーブルが上図です。各セルを (行ラベル, 列ラベル)という組で表すことにすると、例えば (2, E)に4が格納されていることになりますね。
与上述Trie对应的表格如上所示。如果我们将每个单元格表示为一对(行标签,列标签),那么,例如,(2,E)将包含4。
これは、Trie上の「2」というラベルが付いたノードから、文字「E」のラベルがついたエッジを辿ることで、「4」 というラベルが付いたノードに遷移できることを表します。 このようなテーブルを二次元配列などの形式でメモリ上に保持すれば、例えば「AGI」という入力に対してTrie上のノード5に効率よく遷移出来ます。そのことを、Pythonのコードを用いて確かめてみましょう。
这意味着,从Trie中标有 "2 "的节点,沿着标有字母 "E "的边,你可以移动到标有 "4 "的节点。 例如,如果这样的表格以二维数组的形式保存在内存中,就有可能在输入 "AGI "时有效地过渡到Trie上的节点5。让我们用Python代码来验证这一点。
【Python】テーブルによるTrieと共通接頭辞検索ソースコード
Python] Trie和普通前缀按表搜索源代码。
ここからは、GitHubで公開した下記のソースコードを引用しながら解説を進めます。100行に満たないソースコードですが、『日本語入力を支える技術』で解説されている「テーブルによるTrieの実装」をそのまま実現しています。
以下是发布在GitHub上的源代码,不到100行的代码,但它是Trie按表格的实现,如 "日本输入法背后的技术 "中所述。
https://github.com/msato-ok/trie-master/blob/master/tabletrie.py
https://github.com/msato-ok/trie-master/blob/master/tabletrie.py
まず辞書の生成ですが、’MyTrie’というクラスでTrieを表すものとし、’MyTrie’のオブジェクトが一つの辞書を表します。オブジェクトを生成する際には、語彙が格納された配列を入力します。
第一步是生成一个字典,用一个叫'MyTrie'的类代表...