== 高级主题

=== Wordnet

:imagesdir: images

分词系统中需要一个数据结构来表达一段文字来多种分词可能性。距离来说"商品和服务"，"商品/和服/务"就是其中一个 错误的切分可能。 各种分词算法的目标就是找出最合理的切分方法。

image::wordnet-g.png[词图篱笆网络,600]

站在每个字的角度来看，会有一个或多个跳转路径。从Start节点到End节点中必定存在一个最优路径，这个路径就是 分词结果了。但是上图如果利用Node和Edge的数据结构来表达的话，性能和方便程度都很差。

Wordnet是经典的数据结构，mynlp用链表的方式实现了一个高效的Wordnet类。


image::wordnet.png[,600]
每个数字节点，表示一个边，也表示从当前这个字构成的词的长度。

对应的Java数据为：

image::wordnet-ds.png[,600]

每个字对应一个`VertexRow`,每个VertexRow指向一个Vertex链表，其中Vertex链表中的数字大小**一定是不可重复且有序的**。

分词的基本逻辑就是填充Wordnet，使用路径选算法从多种可能性选出最佳的分词路径。

=== Wordpath

类Wordpath表示一个路径，如果路径不在变化，那么也就无所谓采用什么数据结构。但是在Pipeline中，不同的组件和算法还需要对这个 **唯一的路径再进行修改**。会涉及到很多`联合`、`打破-再联合`等操作。在List的基础上操作起来，代码非常复杂且不容易理解。

这里我们使用BitSet来表示唯一分词路径。

image::wordpath.png[,600]

图中的字之间的斜线，表示要切断。我们用bitset中和字对应的Index，设置为true。 比如"提高"是一个词，那么设置bitset的下标1为true。

就是这么简单，使用这种数据结构的好处是，combine或者划词的操作非常简单，而且内存上消耗非常非常低。

=== Injector IOC容器