一种基于cedar双数组字典树算法进行术语匹配的方法与流程

文档序号:12121346阅读:469来源:国知局
一种基于cedar双数组字典树算法进行术语匹配的方法与流程

本发明属于计算机通信领域,尤其涉及一一种基于cedar双数组字典树算法进行术语匹配的方法。



背景技术:

目前翻译行业不断扩大,语料和术语的增长速度都比较快,且数目也比较大。而大量术语是翻译的基石,必须使用有效的信息化技术手段来对它们进行管理。目前公司内部关于术语的原文、译文以及其它详细信息存放于mongo数据库,直接查询数据库来获取原文或译文速度很慢,而原文或译文可能过长,也不便作为索引字段。现有一套术语匹配引擎实现,用双数组算法对术语建立外围索引,然后用将双数组建立的索引与mongo数据库里每条术语记录的Objectld(相当于数据库关键字字段)相关联并存放于redis作为二级索引缓存,最终加快对mongo数据库的查询速度。而在这套匹配引擎系统里,选择双数组字典树算法作为其核心模块,不论建索引还是查询速度,要求都比较高。

双数组字典树算法是翻译行业文本处理一种通用的算法,可以对术语建索引,对术语进行前缀模糊查询,对术语进行精确查询等。一般该算法扩展开来可用于高效的分词,在术语匹配引擎里我们用它来做基于mongo术语数据库快速建索引。双数组字典树,即双数组Trie(Double-ArrayTrie),主要包含base,check数组,根据不同的算法实现可能有tail数组,base数组和check数组根据算法的不同也会有不同的表现形式(比如,混合在结构体内部)。

目前通用的双数组字典树算法实现库是libdatrie,查询效率比较高,但在大量插入数据的情况下就会显得速度很慢,主要就是频繁地解决插入冲突以及在大量数据插入的情况下不断调整tail数组导致的。libdatrie的实现由于base和check之间的关系采用加减运算关系,当存储的字符串是中文时,由于中文字符编码过长就会使得双数组base与check之间对应的下标差距过大,从而产生很多未初始化的元素,也加大了查询时遍历双数组的时间开销,以及解决插入冲突的调整成本。cedar双数组算法直接采用位运算来得出base与check之间的关系,并压缩base与check之间的差距。此外cedar双数组算法在数据结构的设计上也采取了一些优化手段,减少了一些中间计算量。



技术实现要素:

本发明所要解决的技术问题是目前基于数据库的术语匹配引擎在查词效率上速度偏慢,而改善这一问题的办法就是对数据库里的术语建一个快速索引,引入双数组字典树可以解决大量术语建索引慢以及查询慢的问题。

为解决上述技术问题,本发明提供了一种基于cedar双数组字典树算法进行术语匹配的方法,其特征是包括建索引的步骤,及用索引进行术语查询匹配的步骤;

其中,所述建索引的步骤是遍历数据库,获取术语集合,调用cedar双数组字典树插入术语,用以形成术语集合的索引;

所述cedar双数组字典树包括一个以基准值和校验值为成员的结构体数组,一个循环队列;

所述调用cedar双数组字典树插入术语的步骤包括:

(1)根据计算式集合一获取插入术语和双数组字典树的初始化数值,所述计算式集合一为:

from[0] = 0

to[0] = 0 ^ key[0]

from[1] = to[0]

array[0].base=0

array[0].check=0

(2)根据check值和计算式二,计算ehead值,所述计算式二为:

queue[from[pos+1]].ehead = array[from[pos+1]].check

(3)遍历术语中的每个字符,获取插入术语的字符值,根据计算式集合三计算得出双数组字典树的基准值和校验值,所述计算式集合三如下:

array[from[pos+1]].base = queue[from[pos+1]].ehead^ key[pos]

to[pos + 1] = array[from[pos]].base ^ key[pos]

array[to[pos + 1]].check = from[pos]

from[pos + 1] = to[pos]

所述pos为遍历到的字符在术语中的当前位置值,所述key[pos]为插入术语中当前位置的字符值;

所述array为双数组,queue为循环队列,base为基准值,check为校验值,ehead为循环队列中第一个元素成员的下标值;

所述from[pos]和to[pos]分别为当前位置的字符在双数组中所对应的起始下标值和结束下标值,

其中,所述用索引进行术语查询匹配的步骤是:遍历术语的每一个字符,将字符值代入计算式集合四,以array[to[pos + 1]].check=from[pos]为返回条件,直到遍历完,返回该术语在双数组中的位置;

所述计算式集合四如下:

from[0] = 0

to[pos+1] = array[from[pos]].base ^ key[pos+1]

所述key表示要查询的术语,pos为当前遍历到的字符在key中的位置值。

进一步,所述cedar双数组字典树还包括一个用来存放字符所组成的父子以及兄弟关系的二叉树数组;

所述调用cedar双数组字典树插入术语的步骤还包括根据插入术语构建二叉树数组, 所述构建二叉树数组的方法是获取术语里的字符间的父子及兄弟关系。

进一步,所述调用cedar双数组字典树插入术语的步骤还包括对双数组字典树与插入术语进行冲突处理,构建双数组的过程中,如果计算出的基准值和校验值是之前已经存在了的有效值,寻找没有被占用的双数组节点,然后再遍历术语里的每个字符,算出后续的所有双数组节点。

进一步,所述数据库为mongo数据库。

进一步,所述索引为双向索引。

进一步,所述索引是建立在术语语料所在的数据库之外。

进一步,所述索引包括一级索引和二级索引。

进一步,还包括当索引达到数量阈值后写入硬盘。

进一步,所述循环队列与结构体数组体量相同。

采用上述技术方案,可达到以下效果:

将cedar双数组算法应用于术语匹配引擎的建索引和根据索引来查询术语,极大地提升了术语匹配引擎的效率,同时该算法也避免了传统算法对大量术语建索引时速度非常慢而不利于快速重建数据的缺点;二叉树作为一种辅助结构,可以用来快速地还原整个双数组字典树。

附图说明

此处所说明的附图用来提供对本发明的进一步理解,构成本申请的一部分,本发明的示意性实施例及其说明用于解释本发明,并不构成对本发明的不当限定,在附图中:

图1示出了基于cedar双数组字典树算法进行术语匹配的方法的流程示意图;

图2示出了调用cedar双数组字典树插入术语的步骤的的流程示意图;

图3示出了结构体数组array[n]的结构示意图;

图4示出了循环队列queue[n]的结构示意图;

图5示出了二叉树数组ninfo[n]的结构示意图;

图6示出了sibling数组的父子及兄弟关系的示意图。

具体实施方式

下面结合附图和具体实施方式对本发明的技术方案作进一步具体说明。

为解决上述技术问题,如图1所示,本发明提供了一种基于cedar双数组字典树算法进行术语匹配的方法,其特征是包括建索引的步骤,及用索引进行术语查询匹配的步骤;

其中,

1.所述建索引的步骤是遍历数据库,获取术语集合,调用cedar双数组字典树插入术语,用以形成术语集合的索引;

所述cedar双数组字典树中,每个数组元素包括一个以基准值和校验值为成员的结构体数组array[n](如图3所示),一个与结构体数组体量相同的循环队列queue[n],以及一个用来存放字符所组成的父子以及兄弟关系的二叉树数组,即sibling数组ninfo[n];

如图4所示,一个与结构体数组体量相同的循环队列,循环队列queue[n],每个元素就是一个block,ehead代表第一个打开的block的下标,chead下标对应的block是当前已满(block,num > 256)的元素,fhead下标对应的block是从上一个chead下标对应的block转过来的;block包含成员int prex、int next、short num、short reject、int trial、int ehead;

sibling数组ninfo[n]如图5所示,child表示遍历字符串时,当前的那个字符,sibling表示child父节点的右兄弟,sibling数组与结构体数组和循环队列没有必然的逻辑关系,可以剥离出来,目的是在构建双数组字典树的同时构建sibling数组,用于在双数组字典树损害的时候实现快速恢复还原。

sibling数组的父子及兄弟关系如图5所示, 每个节点顶多只有一个子节点,就是该节点所对应的字符的一个后继字符,而节点的兄弟节点就是自它的parent节点即父节点向下的每一层的sibling节点。

如图2所示,向双数组字典树中插入术语就是给双数组字典树中的元素赋值的过程,所述调用cedar双数组字典树插入术语的步骤包括:

(1)根据计算式集合一获取插入术语key和双数组字典树array的初始化的基准值base和校验值check,所述计算式集合一为:

from[0] = 0

to[0] = 0 ^ key[0]

from[1] = to[0]

array[0].base=0

array[0].check=0。

(2)根据结构体数组的check值和计算式二,计算循环队列的ehead值,所述计算式二为:

queue[from[pos+1]].ehead = array[from[pos+1]].check

第一次check值取自步骤(1),后续check值取自步骤(3),循环队列里保存每次最新计算一个结构体数组元素之后的check成员值,每次插入术语里一个新的字符时,先从循环队列里取出上一次最新的check值以计算出下一个双数组元素的ehead值;

可见,循环队列中的ehead值由结构体数组里的check值计算得出。

(3) 遍历术语中的每个字符,往双数组字典树顺序每次插入一个字符,就会即时产生字符在术语中的位置值,根据计算式集合三和ehead值计算得出双数组字典树的基准值和校验值,所述计算式集合三如下:

array[from[pos+1]].base = queue[from[pos+1]].ehead^ key[pos]

to[pos + 1] = array[from[pos]].base ^ key[pos]

array[to[pos + 1]].check = from[pos]

from[pos + 1] = to[pos]

循环队列里保存每次最新计算一个结构体数组元素之后的check成员值,每次插入术语里一个新的字符时,先从循环队列里取出上一次最新的ehead值以计算出下一个双数组元素的base值。

所述pos为遍历到的字符在术语中的当前位置值,所述key[pos]为插入术语中当前位置的字符值;

所述array为双数组,queue为循环队列,base为基准值,check为校验值,ehead为循环队列中第一个元素成员的下标值;

所述from[pos]和to[pos]分别为当前位置的字符在双数组中所对应的起始下标值和结束下标值。

(4)根据插入术语构建sibling树即二叉树数组:

构建二叉树数组的过程就是提取术语里的字符间的父子及兄弟关系,然后以数组的形式存放。该树作为一种辅助结构,可以用来快速地还原整个双数组字典树。

(5)双数组插入冲突处理:

在构建双数组的过程中,计算出的base和check可能是之前已经存在了的有效值,那么就要处理冲突的问题,解决冲突就是寻找没有被占用的双数组节点,然后再遍历术语里的每个字符,逐渐地算出后续的所有双数组节点。

2.用cedar双数组字典树形成的索引进行术语查询匹配:

用cedar双数组字典树形成的索引进行术语查询匹配就是遍历术语的每一个字符,将字符代入双数组字典树计算式集合四进行计算,满足条件则继续,直到查完,然后返回该字符串在双数组中的位置。

所述计算式集合四如下(key表示要查询的术语,pos为当前遍历到的字符在key中的位置):

from[0] = 0

to[pos+1] = array[from[pos]].base ^ key[pos+1]

按照以上逻辑计算后,检查array[to[pos + 1]].check和from[pos]是否相等,如果不相等,则直接返回失败,否则继续,直到遍历完,然后返回最后一个字符的base值。

用索引进行术语查询匹配的步骤,该base值即插入术语时所设置的整数标识值,根据该整数标识值计算二级索引的ID。

在建索引的过程中,遍历mongo数据库里指定的术语,读出原文与译文并分别算出指定长度的字串前缀的hash值,根据hash值确定数据落入哪个字典树里,然后用cedar双数组算法进行建索引,建索引就是前面技术方案里所述的插入术语的过程。所有的索引树都放到内存里,为防止数据丢失,会定时保存到磁盘。查询时先计算指定长度的字串前缀的hash值,根据hash值确定数据落入哪个字典树里,然后到指定的双数组树里去查询,术语查询的过程如上面技术方案里所述。

基于双数组字典树和内存缓存系统来存放外围索引信息,将较长的原文或译文映射为数据库内全局唯一且带有快速索引的记录ID字段,从而加速了术语的匹配,同时借助双数组的特性,也具备分词,前缀查询等翻译行业所需的功能。

本领域技术人员还应当理解,以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1