FST(Finite State Transducer)算法的概念在这篇博客中并不涉及,网上有太多的资料啦,写的都非常的不错。这里推荐这位网友的介绍:https://www.shenyanchao.cn/blog/2018/12/04/lucene-fst/ 。如果链接失效了,可以看附件中的副本。本文中,我们基于一个例子来介绍在Lucene中如何构建FST。感谢网友关新全的分享,基于他的分享使得我在看源码的时候事半功倍,在此基础上,增加一些更加贴近源码的内容。同样的,关新全同学分享的文章在附件中。

准备工作

  为了便于理解,先介绍几个概念。

current[ ]数组

  构建FST后生成的信息都最终保存到字节数组current[ ]数组中,即生成FST的最终结果就是该数组。

Node(节点)、Arc(弧、边)

  在下文的介绍中使用节点跟弧(边),即有向无环图的概念来描述生成的过程,Node之间使用一个Arc连接,一个Node跟一个或多个Node连接。

  Node还具有两种状态:UnCompiledNode和CompiledNode。在源码中,使用两个对象来描述这两种状态,如下所示:

图0:

Lucene FST算法

  当开始处理某个输入值时,会将它的信息生成Node跟Arc,此时Node的状态为UnCompiledNode,当Node以及它的出度对应的Arc(出边)的信息写入到current[ ]之后,Node的状态转变为CompiledNode。 例如图1中当开始处理的输入值为mop时,会生成4个状态为UnCompiledNode的Node以及3个Arc,其中Node1的出边为arc1,以此类推。我们给出源码中UnCompiledNode类的定义来理解Node跟Arc的关系:

图0-1:

Lucene FST算法

图0-2:

Lucene FST算法

  图0-2描述的是Arc在源码中的定义,由图0-1可知,一个状态为UnCompiledNode的Node使用Arc<T>数组来描述它的出度的值,可以见该值是大于等于0的,即一个状态为UnCompiledNode的Node中可以包含多个Arc。

  图0-1跟图0-2中的其他变量的概念在下文中我们会根据需要一一介绍。

图1:

Lucene FST算法

label、target

  基于图1我们先介绍下图0-2中Arc类的两个成员域:label和target,假设有一个输入值 “mop”,会使用三个Arc<T>对象来分别描述“m”,“o”,“p”的三个字符的信息,并且这三个对象分别是三个状态为UnCompiledNode的Node的出边。描述“m”的Arc<T>对象arc1,它是Node1的出边,对象arc1中的label的值是 109,即“m”的ASCII值;对象arc1的target的值即Node2,这里暂时不讨论isFinal、nextFinalOutput的含义,后面会涉及。另外如果Node没有任何的出度,那么它是一个终止节点

output

  output值是某个输入的附加值(payload),比如有输入值”mop”,它的附加值是100,但是对于分别封装了"m",“o”,“p”的三个arc,附加值100应该存放哪个arc的output字段呢?下面通过一个例子来说明:

 

 

1

例子:输入为 “mop”、“mt”,附加值分别是100、91。

处理“mop”, 100

图2:

Lucene FST算法

  只处理输入"mop"时,附加值是放在“m”的arc中。

 

看这里:https://www.amazingkoala.com.cn/Lucene/yasuocunchu/2019/0220/35.html

相关文章: