用于任意规模词典的完美哈希函数构造方法及系统 【技术领域】
本发明涉及词典中单词、关键字的一次比较和检索,更具体地涉及用于任意规模词典的完美哈希函数构造方法及系统。
背景技术
词典索引与查找是自然语言处理中最基本的问题。编译器中关键词和预定义标志符的判断、IDE中关键词的着色、编辑器中的拼写检查、搜索引擎的关键词Postlist定位、停用词的判定以及中文分词等领域都有着广泛的应用。
词典索引和查找的研究有着很久的历史。常用的索引方法有线性表的二分(折半)查找、各种搜索树和哈希法等。由于线性表要采用二分查找,需要表是一种有序表,查找效率与线性表的长度有关。典型的搜索树包括B+,B-,TRIE树等,其时间复杂度是树的深度,但一般索引占用存储空间很大。哈希法通常只需一次查找,是最高效的查找方法,因此在多数场合受到优先选择。其关键技术是哈希函数的设计,采用合理的方式控制数据分布的均匀性,减少冲突,提高空间利用率。但哈希法一旦发生映射冲突,就降低了搜索效率。研究者把不发生冲突的哈希函数称为完美哈希函数。
在完美哈希函数的研究中,Cichelli首次提出一种可行的最小完美哈希函数的构造算法,但是该方法无法区别长度相同、首字母也相同的单词,而且构造速度比较慢。其最致命的缺点是词典中单词超过45个时基本上找不到哈希函数。David Alan Wolverton针对Cichelli算法无法解决Ada语言保留字的完美哈希问题,提出单词哈希值的计算方法,但是仍然只能针对小词典构造哈希函数。在此基础上Nick Cercone等人对哈希函数做了大量工作,但是仍然无法解决大词典问题。Chang利用中国剩余理论,提出了一种针对质数序列构造保序最小完美哈希函数的方法。由于其质数产生器只能产生40个左右质数,同时不能针对字符串构造哈希函数,因此其方法作用很有限,基本上只有数学意义。Sager提出的Mincycle算法原理上能够处理大规模词典,但是有些情况对小词典也不一定有效。Linux系统下著名的完美哈希函数生成器gperf,不能保证每次运行都能找到词典的完美哈希函数,而且词典中词条数目过大(超过10000条)时装填因子将非常低。在相关技术中,完美哈希函数构造主要依赖于相应词典的平滑函数构造,但是相应词典的平滑函数系数选择比较困难,而且当单词条目数太多时,也会产生关联表过长,装填因子很低等问题。可以看出,为词典构造完美哈希函数是一项非常困难的工作。
【发明内容】
为了解决上述技术问题,本发明提供了一种用于任意规模词典的完美哈希函数构造方法,包括:步骤1:按照词典或关键字集合建立TRIE树;步骤2:确定单词关联长度k;步骤3:从所述TRIE树的k层开始直到0层,自底向上逐层计算组成所述词典的各个字符在每一层上的关联值;以及步骤4:根据计算出的所述单词关联长度和各个字符在每一层上的所述关联值来实现所述词典到哈希表的完美映射。
根据本发明的一个实施例,所述步骤3进一步包括:步骤31:获得所述TRIE树中第l层的所有结点;步骤32:初始化所述第l层的所述所有结点的每一个子结点的空间占用范围;步骤33:将所述第l层的所述所有结点的子结点的所述空间占用范围转成基本项;步骤34:把所有所述基本项按照指定优先级在线形空间内排列并相互叠加、合并为一体,在确保非空位置不产生重叠的情况下,使合并后占用的空间最小;步骤35:计算所述第l层的字符关联值以及每一结点的空间占用范围,同时,将l层每一结点的空间占用范围传递给所述TRIE树的l-1层相应的父结点,其中l是从k到0的整数,其中基本项与组合项相对应,统一称之为项。
根据本发明的一个实施例,在所述步骤33中,将所述第l层的所有结点转成基本项地过程中,将所述TRIE树的所述第l层的所有结点的子结点的空间占用情况用一个矩阵An×m来表示,m表示所述TRIE树的结点的分支个数,n表示l层中树结点中的个数,矩阵A是通过将所述TRIE树中所述第l层的所有结点的子结点空间占用情况从左到右采集下来,相同字符所代表的子结点在同一列上,每个结点作为一行,从左到右、从上到下依次放入矩阵A中,每一列被认为是一个基本项,形成m个基本项。
根据本发明的一个实施例,基本项包括以下特征:空行项:基本项的某一行上的所有空间均未被占用;非空行:基本项的所有行上都存在占用空间;平型:基本项中所有Back_Idle与Front_Idle都为0;凸凹:平型项以外的所有基本项;单列项:基本项由一个列构成;以及多列项:基本项包括多个列。其中,步骤34进一步包括:步骤341:将所述基本项按照基本项的特征分为类Ⅰ、类Ⅱ、类Ⅲ和类Ⅳ四个类别,其中,所述类Ⅰ具有多列、非空行以及凸凹的特征;所述类Ⅱ具有多列、空行的特征;所述类Ⅲ具有单列、空行的特征;以及所述类Ⅳ具有单列、非空行的特征;步骤342:处理所述类Ⅰ中的项,对满足封装数为0的任意两项进行合并,生成组合项,并记录基本项之间的合并关系,生成的组合项加入类Ⅰ中继续参与合并运算;步骤343:将所述类Ⅰ中的剩余项加入到所述类Ⅱ中;步骤344:按照优先合并指标、在所述类Ⅱ中合并度大于0的各项之间进行逐步合并,并记录基本项之间的合并关系,也将合并过程中封装在内部的空闲单元以单列项的形式记录下来,形成待填充项,同时也记录下这些待填充项在合并项中的位置;步骤345:将所述类Ⅱ中的剩余项进行排序,使它们按照这种排序进行合并时封闭在内部的空闲单元最少,然后依据所述排序将所述类Ⅱ中的项合并成临时项T,并依据所述临时项T继续生成或合并待填充项;步骤346:将所生成的待填充项与未被所述临时项T封装的空闲空间依据位置进行合并,并依据待填充项被所述临时项T封装在内部数目的多少来对待填充项从小到大排序;步骤347:依据待填充项将所述类Ⅲ中的项尽量地合并到所述类Ⅱ中的项中,并记录基本项之间的合并关系;步骤348:将所述类Ⅲ中的剩余基本项合并成单列项,记录基本项之间的合并关系,并确保这些合成的单列项之间不能继续合并;以及步骤349:将所述类Ⅱ、所述类Ⅲ、所述类Ⅳ中的剩余项进行排序,并按照这种排序将它们合并成一个项,并使封闭在内部的空闲空间最小。
根据本发明的一个实施例,在步骤35中,利用合并关系以及每个基本项的宽度计算每个基本项所对应的字符的关联值。
本发明还提供了一种用于任意规模词典的完美哈希函数构造系统,包括:TRIE树构造模块,连接到词典文件,用于根据词典或关键字集合建立TRIE树;确定单词关联长度模块,连接到所述TRIE树构造模块,用于确定单词关联长度k;分层关联值设置模块,连接到所述确定单词关联长度模块,用于从所述TRIE树的第k层开始,自底向上逐层计算组成所述词典的各个字符在每一层上的关联值,并把关联值存放于关联表中;以及完美映射模块,连接到所述分层关联值设置模块,用于根据由所述确定单词关联长度模块计算出的所述单词关联长度和由所述分层关联值设置模块计算出的各个字符在每一层上的所述关联值来实现所述词典到哈希表的完美映射。
根据本发明的一个实施例,分层关联值设置模块包括:初始化模块,用于初始化所述TRIE树的所述第l层的所有结点的空间占用信息;基本项生成模块,用于依据所述TRIE树的所述l层的每一结点的空间占用信息来生成基本项;合并模块,用于把由所述基本项生成模块生成的所有所述基本项按照指定优先级在线形空间内排列并相互叠加、合并为一体,在确保非空位置不产生重叠的情况下,使合并后占用的空间最小;关联值计算模块,用于依据所述合并模块的最终合并结果,计算所述字典的组成字符在本层的关联值;以及空间占用信息上传模块,用于将l层结点的空间占用情况传给l-1层中相应的父结点。
根据本发明的一个实施例,合并模块包括:基本项分类模块,连接到所述基本项生成模块,用于计算所述TRIE树的所述l层的所有基本项的特征值,并依据每个基本项中各个基本项的特征,将每个基本项分为类Ⅰ、类Ⅱ、类Ⅲ和类Ⅳ四个类别,其中,所述类Ⅰ具有多列、非空行以及凸凹的特征;所述类Ⅱ具有多列、空行的特征;所述类Ⅲ具有单列、空行的特征;以及所述类Ⅳ具有单列、非空行的特征;类Ⅰ自身合并模块,连接到所述基本项分类模块,用于将所述类Ⅰ中的各项之间合并封装数为0的项之间进行合并,并记录基本项在合并项中的起始位置,将合并后的项加入类Ⅰ中参与新的运算;当类Ⅰ中任意两项之间封装数都大于0时,将所述类Ⅰ中的剩余项加入到所述类Ⅱ中;类Ⅱ自身合并模块,连接到所述类Ⅰ自身合并模块,用于将所述类Ⅱ中合并度大于0的项之间依据优先合并指标,进行先后合并,合并后的组合项放入类Ⅱ中继续参与合并,直到任意两项的合并度都为0,并在合并过程中记录下相应的待填充项,以及基本项在合并项中的起始位置;类Ⅱ项填补模块,连接到所述类Ⅱ自身合并模块,用于将所述类Ⅲ中的基本项尽可能合并到所述类Ⅱ中的项所包含的空闲单元中,直到所述类Ⅲ中的基本项再也无法合并到类Ⅱ的项中;类Ⅲ自身合并模块,连接到所述类Ⅱ填补模块,用于将所述类Ⅲ中满足合并度大于0的基本项进行合并,且确保合并后占用的列数最少,并录记录基本项之间的合并关系;无关项排序模块,连接到所述类Ⅲ自身合并模块,用于将所述类Ⅱ、所述类Ⅲ、所述类Ⅳ中的所有项进行排序,使得各项按照这种排序合并后,封装在内部的空闲空间数最小;以及无关项合并模块,连接到所述无关项排序模块,用于按照所述无关项排序模块给出的排序关系对所述类Ⅱ、所述类Ⅲ、所述类Ⅳ中的项进行合并,并录记录基本项之间的合并关系。
根据本发明的一个实施例,类Ⅱ项填补模块包括:无关项排序模块,用于将所述类Ⅱ中的项进行排序,使得各项按照这种排序合并后,封装在内部的空闲空间数最小;无关项合并模块,用于将所述类Ⅱ中的项按照所述无关项排序模块中给出的排序关系合并成一个临时项;最终待填充项序列生成模块,用于将所述类Ⅱ中的项的所有空闲单元与待填充项合并,生成新的待填充项,并将这些待填充项按照未被所述无关项合并模块中生成的临时项封闭在内部的多少从少到多排序;填补关系生成模块,用于针对所述最终待填充项序列生成模块给出的每一个待填充项,依据排序关系,逐个寻找其由所述类Ⅲ中哪些基本项组成将使其剩余的空闲空间最少以生成填补关系;以及逐项填补模块,用于依据所述填充关系生成模块生成的所述填补关系、待填补项与所述类Ⅱ中项的关系,将所述类Ⅲ中的基本项合并到所述类Ⅱ的相应项中,并录记录基本项之间的合并关系。
根据本发明的适用于任意规模词典的完美哈希函数构造方法和系统,构造出一个更优秀的字典完美哈希函数,实现字典中单词到哈希表的完美映射。其利用关联值相加可以快速判断一个单词是否属于词典,而且本发明在增加哈希表空间利用率方面进行了设计,降低了词典索引的空间复杂度。由于本发明给出的Hash函数构造方法,内存占用空间在同类索引中相对较小,可将其应用于对速度和空间要求高的应用系统中。
【附图说明】
通过下面结合附图的具体描述可以更清楚地理解本发明的上述和其他方面、特征以及其他优点。
图1是可视化形式表示项以及哈希表中的一个位置的示意图;
图2是封装和实心列的示意图;
图3是根据本发明的任意规模词典的完美哈希函数构造方法的流程图;
图4是根据本发明的任意规模词典的完美哈希函数构造系统的结构图;
图5是根据本发明的一个实施例的完美哈希函数构造系统的结构图;
图6是根据本发明的一个实施例的分层关联值设置模块的结构示意图;
图7是根据本发明的一个实施例的合并模块的结构示意图;
图8是根据本发明的一个实施例的类Ⅰ存储和合并示意图;
图9是根据本发明的一个实施例的类Ⅱ项填补模块的结构示意图;
图10示出了根据本发明的一个实施例的待填充项的示例;
图11示出了根据本发明的一个实施例的无关项排序模块中的排序过程的示例;
图12示出了根据本发明的一个实施例的无关项最优排序搜索过程;以及
图13示出了根据本发明的一个实施例的关联值计算的示意图。
【具体实施方式】
下面将参考附图具体描述本发明的示例性实施例。
为了使本发明能更易理解,给出了如下一些定义和说明:
定义1:在本发明中,哈希表中的一个位置,以可视化的形式表示成一个矩形,它有两种状态,即空闲和占用:
空闲(idle):表示这个空间位置还没有和字典中的某一个词存在映射关系;
占用(occupied):表示这个空间位置已经和字典中的某一个词存在了映射关系。
定义2:项:可以形象的用一个积木版来表示,其可视化描述如图1所示,并分为空闲和占用两种组成单元,与哈希表中空间的空闲与占用相对应,即是否同字典中的某个词存在映射关系。项分为基本项和组合项两种:
基本项指由l层结点的子结点占用空间直接经过相应矩阵A转化而来,与所述词典的相应字符存在对应关系;
组合项:由基本项、组合项合并而成的项。
定义3:合并:两个项在线性空间内相互交叠合成为一个项,但占用单元之间不能重叠。
定义4:合并度:两个项在线性空间内合并时,后者嵌入前者的长度。
定义5:无关项:合并度为0的两个项;
定义6:待填充项:合并时封装在内部的空闲单元用项的形式表示出来,以便后来再用其它项将其填补为占用状态。
定义7:封装数:被占用单元线性包围在内部的空闲单元数(如图2所示)。
定义8:实心列:指项中不含空闲单元的列(如图所示2)。
定义9:单列项:具有单列特征的项。
为解释和说明本发明,定义了一些基本变量:
Front_Idle:位于项头部某一行中的空闲单元数(空行不计算Front_Idle);
Back_Idle:位于项尾部某一行中的空闲单元数(空行不计算Front_Idle)。
图3是根据本发明的任意规模词典的完美哈希函数构造方法的流程图。如图3所示,根据本发明的用于任意规模词典的完美哈希函数构造方法包括:步骤S302:按照词典或关键字集合建立TRIE树;步骤S304:确定单词关联长度k;步骤S306:从所述TRIE树的k层开始直到0层,自底向上逐层计算组成所述词典的各个字符在每一层上的关联值;以及步骤S308:根据计算出的所述单词关联长度和各个字符在每一层上的所述关联值来实现所述词典到哈希表的完美映射。
根据本发明的一个实施例,上述步骤S306中进一步包括:
步骤31:获得TRIE树中第l层的所有结点;
步骤32:初始化l层结点的每一个子结点空间占用范围;
步骤33:将l层结点的子结点空间占用范围转成基本项表示;
步骤34:合并所有项;
步骤35:设置l层的字符关联值,同时,将l层每一结点的空间占用范围传递给所述TRIE树的l-1层相应的父结点,其中l是从k到0的整数,其中基本项与组合项相对应,统一称之为项。
其中步骤S33中包括:将l层结点转成基本项表示的过程中,将TRIE树的第l层结点的子结点的空间占用情况用一个矩阵An×m来表示,m表示树结点的分支个数,n表示l层中树结点中的个数,矩阵A的生成办法则是将TRIE树中l层结点的子结点空间占用情况从左到右采集下来,相同字符所代表的子结点在同一列上,每个结点作为一行,从左到右、从上到下依次放入矩阵A中,这样每一列认为是一个项,形成m个项。
在步骤34中,将项比作积木板,把所有项按照某种优先级在线形空间内排列并相互叠加、合并为一体,在确保非空位置不产生重叠的情况下,使合并后占用的空间最小。
在步骤35中,还包括:利用合并关系(包括合并先后、合并度)以及每个基本项的宽度来设置每个基本项所对应字符的关联值。
根据本发明的一个实施例,步骤34中进一步包括:
步骤341:将基本项分为Ⅰ、Ⅱ、Ⅲ、Ⅳ等4个类别。
步骤342:处理类Ⅰ中的项,对满足封装数为0的任意两项进行合并,生成组合项,并记录基本项之间的合并关系,生成的组合项加入类Ⅰ中继续参与合并运算;
步骤343:将类Ⅰ中的剩余项加入到类Ⅱ中;
步骤344:按照优先合并指标、将类Ⅱ中合并度大于0的项之间进行逐步合并,生成组合项,并记录基本项之间的合并关系,也将合并过程中封装在内部的空闲单元以单列项的形式记录下来,形成待填充项,同时也记录下这些待填充项在合并项中的位置,同时生成的组合项加入类Ⅰ中继续参与合并运算;
步骤345:将类Ⅱ中的剩余项进行排序,使它们按照这种排序进行合并时封闭在内部的空闲单元最少。然后依据此排序将类Ⅱ中项合并成临时项T,并依据T继续生成或合并待填充项。
步骤346:将所生成的待填充项与未被T封装的空闲空间依据位置进行合并,并依据待填充项被T封装在内部数目的多少对待填充项从小到大排序;
步骤347:依据待填充项将类Ⅲ中的项尽量的合并到类Ⅱ中的项中,并录记录基本项之间的合并关系;
步骤348:将类Ⅲ中的剩余项合并成多个单列项,确保这些单列项之间不能继续合并,记录基本项之间的合并关系;
步骤349:将类Ⅱ、类Ⅲ、类Ⅳ中的剩余项进行排序,并按照这种排序将它们合并成一个项,并使封闭在内部的空闲空间最小。
其中,在步骤341中,分类中使用的基本项特征包括:
特征1:是空行项还是非空行项。
空行项:项的某一行上的所有空间均未被占用;
非空行:项的所有行上都存在占用空间;
特征2:是平型项还是凸凹项。
平型:项中所有Back_Idle与Front_Idle都为0;
凸凹:平型项以外的所有项;
特征3:是单列项还是多列项。
单列项:指项由一个列构成的;
多列项:含有多个列的项;
根据以上的基本项特征可以分为以下类别:
Ⅰ类:多列、非空行、凸凹;
Ⅱ类:多列、空行;
Ⅲ类:单列、空行;
Ⅳ类:单列、非空行。
在步骤344中,其优先合并指标包括:
合并封装数:两个项合并后被占用空间线性包围在内部的空闲单元数;
合并增益层:两个项合并后增加的实心列数;
合并后压缩数:指两个项合并后的空闲空间的减少数。
上述三者的优先性为从上到下依次减小。
根据本发明的适用于任意规模词典的完美哈希函数构造方法,利用TRIE树、积木板在线性空间内的拼插合并机制确定此词典的单词关联长度、组成字符在每一位置上的关联值,从而实现词典到哈希表的完美映射。
图4是根据本发明的任意规模词典的完美哈希函数构造系统的结构图。如图4所示,根据本发明的任意规模词典的完美哈希函数构造系统包括:TRIE树构造模块402,连接到词典文件,用于根据词典或关键字集合建立TRIE树;确定单词关联长度模块404,连接到所述TRIE树构造模块,用于确定单词关联长度k;分层关联值设置模块406,连接到所述确定单词关联长度模块,用于从所述TRIE树的第k层开始,自底向上逐层计算组成所述词典的各个字符在每一层上的关联值;以及完美映射模块408,连接到所述分层关联值设置模块,用于根据由所述确定单词关联长度模块计算出的所述单词关联长度和由所述分层关联值设置模块计算出的各个字符在每一层上的所述关联值来实现所述词典到哈希表的完美映射。
图5是根据本发明的一个实施例的完美哈希函数构造系统的结构图。如图5所示,根据本发明的一个实施例的完美哈希函数构造系统,其包括:TRIE树构造模块、确定单词关联长度模块、分层关联值设置模块。
TRIE树构造模块504:连接到词典文件502,基于构成词典的基本元素数目,读取词典中的词条建立合理的TRIE树。对于基本元素较少的词典或关键字集合,直接采用TRIE树作为存储结构空间浪费处于可接受范围内。对于像汉语这类的电子词典,基本字符在6763个以上(其中GB2312收录简体汉字6763个,GBK收录20912个汉字,最新的GB18030收录27533个汉字,BIG5码收录13053个汉字),这种词典的TRIE树结构中指针空间占用过于浪费。这时,将TRIE树中结点内的子结点之间用链表或可变长数组来表示会大大降低空间占用。
确定单词关联长度模块506:广度遍历TRIE树,寻找子结点个数大于1的最大层次k,这样,k是单词的关联长度,k与构成字典或关键字集合的字符数的积便为关联表长度。然后将k层以下到叶结点之间的结点剪掉,使k+1层全部为叶结点,现在TRIE树也为k+1层。
分层关联值设置模块508:负责从TRIE树k层开始,自底向上逐层计算组成词典的各个字符在每一层上的关联值。
如图6所示,分层关联值设置模块508包括:
初始化模块602,用于初始化所述TRIE树的所述第l层的所有结点的空间占用信息。当处理TRIE树中的k层结点时,如果其子结点连接的是叶结点,则相应子结点的空间占用范围为1,前部空闲空间为0;如果其子结点连接的不是叶结点,则相应子结点的空间占用范围是从其子结点传来的空间占用情况;如果子结点为空,则占用范围为0,前部空闲空间也为0。
基本项生成模块604,用于依据所述TRIE树的所述l层的每一结点的空间占用信息来生成基本项。TRIE树中第l层的基本项生成可按如下五步进行:
第一步:对于TRIE树中的第l层结点的子结点,将其从左到右加入到一个矩阵A中,每行对应一个结点,每列对应于一个子结点的占用情况,所有子结点的空间占用情况均从0开始;
第二步:求矩阵A中含有元素大于2的行,并将此行中含有元素的列加入到List序列中;
第三步:去除不包含在List中的列;
第四步:去除不包含元素的行;以及
第五步:矩阵A的每一列形成一个基本项,记录基本项与构成词典基本字符的关系。
合并模块606,用于把由所述基本项生成模块604生成的所有所述基本项按照指定优先级在线形空间内排列并相互叠加、合并为一体,在确保非空位置不产生重叠的情况下,使合并后占用的空间最小。
如图7所示,合并模块606包括:
基本项分类器702:首先分析每一基本项的三个特征,然后按照这些特征将基本项分到Ⅰ、Ⅱ、Ⅲ、Ⅳ四个桶中。
类Ⅰ自身合并模块704:采用类似于归并排序的算法对类Ⅰ中所有合并封装数为0的项之间进行合并,参考图8可按照如下步骤进行(但不限于此):第一步:对于类Ⅰ中的所有项分别将指针存放于两个缓冲区中,但共享同一个实体。然后对两个缓冲区分别按照Front_Idle_Total和Back_Idle_Total排序。第二步:将Front_Idle_Total等于Back_Idle_Total且不是同一个项的项之间进行合并,并将合并结果存于结果缓冲区中,同时将两项设为used标志。这样带有used标志的项就不能再参与合并运算。第三步:遍历实际元素序列,如果不含有带used标志的项,则合并结束;否则,从实际元素序列中删除所有带有used标志的项,并将合并结果缓冲区中的项加入到实际元素序列中,并跳转到第一步。其中,Front_Idle_Total表示所有Front_Idle的和,以及Back_Idle_Total表示所有Back_Idle的和。
类Ⅱ自身合并模块706:其将完成三项任务:按照优先合并指标,逐步合并类Ⅱ中合并度大于0的项;在合并中,以单列项的形式记录被项合并到内部的空闲单元,形成一系列待填充项;合并中记录每个基本项在合并项中的位置。
因为要考虑合并的优先顺序,在具体实施阶段,可采用如下方法加速合并(但方法不唯一),即首先生成项之间的最大代价树,然后利用此生成树尽可能一次多合并最优项,并记录下待填充项。
项的最大代价生成树是以各项作为顶点、优先合并指标为权重的图的最大代价生成树,即:对于图中的任一个顶点,只选取与其连接的、优先合并指标最好的一条边,针对所有顶点选择完毕后,其它边都去除。
在利用生成树寻找最优合并项进行合并时,可采用的具体方法如下:设N={V,{E}}是项集合的最大代价生成树,V表示要合并的项的集合,{E}表示V中所有项之间的最优合并关系的集合。设i=0;Tj.V为项Tj的组成结点的集合,然后进行以下的步骤:
第一步:如果{E}为空,则搜索完毕,否则,取当前E中权重最大的一条边(u,v),即u与v的合并,并将其从E中删除;
第二步:如果u,v都不属于任何Tj.V,则将(u,v)生成项Ti,并将u,v加入到Ti.V,状态Wi=unFinished,跳到第一步;
第三步:如果u,v都在Tk中,则跳到第一步;
第四步:如果u,v分别在Tk.V、Tj.V中,如果Wk、Wj都为unFinished,且将Tk、Tj合并结果大于{E}中的最大边,则将Tk、Tj合并,合并后的状态为unFinished,且将Tk.V与Tj.V合并,否则将Wk、Wj都设为Finished,跳到第一步;
第五步:如果u或v只有一个位于T中,二者处理相同。以u在Tk为例。如果u在Tk中,Wk=unFinished,如果Tk与v合并结果大于{E}中的最大边,则将Tk与v合并,v加入到Tk.V中;跳到第一步。
在类Ⅱ中,项之间合并时,当封装数大于0时,则以单列项的形式记录封闭在内部的空闲单元,形成待填充项,并记录待填充项在所在项中的位置。如图10所示,(a)是合并后的项,(b)和(c)是空闲单元以单列项的形式加以表示,空白表示在(a)中已经占用;灰色表示未被占用。
在合并过程中,还可能出现待填充项之间叠加,是否需要叠加主要依据两个待填充项是否在同一列上,如果在同一列将进行集合并运算。
类Ⅱ项填补模块708,连接到类Ⅱ自身合并模块706,用于将所述类Ⅲ中的基本项尽可能合并到类Ⅱ中的项所包含的空闲单元中,直到类Ⅲ中的基本项再也无法合并到类Ⅱ的项中。如图9所示,类Ⅱ项填补模块708包括:
无关项排序模块902:当一个项集合已经无法通过空间叠加的方式,减少空闲空间,只能通过排序的方式使这些项在合并过程中将尽可能少的空闲单元封闭在内部。而通过排序使封闭在内部的空间最小时,则需要两侧未封闭的空闲单元数最大。基于这种思想,在实施阶段采用了从头尾两侧同时向中间逐步寻找最优排序的方法,如图所示11,具体方法如下:
设计一个堆栈和两棵搜索树来辅助实现启发式搜索(如图12)。其中,堆栈用来记录和控制处理结点的先后顺序,内容包括:处理的是哪一棵树,以及哪一个结点。两棵搜索树的根结点分别是序列中的头、尾结点。
在两棵搜索树中,分别存在一个当前可扩展结点,其子结点是与其关联的所有项,且子结点之间依据其与相应父结点(当前可扩展结点)之间的空行相交度的大小,从左到右排序。
入栈规则:从每棵搜索树的当前可扩展结点的子结点中选择相交度最大的、且未在堆栈中出现的子结点分别设为候选当前可扩展结点;如果当前可扩展结点的子结点已经搜索完毕,则选择其兄弟结点中的、未访问过的、且未在堆栈中出现的结点作为当前候选结点。当两个当前候选结点选择完毕后,则在两个当前候选结点中选择会使空闲单元数更大的结点作为相应搜索树的当前可扩展结点,并使该结点入栈;
回溯规则:当Cur_Idle_Num+Expect_Idle_Num+RowNum*ElseWidth<=Max_Idle_Num,则将栈顶所在搜索树的当前可扩展结点下的所有分枝剪裁掉,即:将栈顶元素出栈,取其未访问过的兄弟结点中、与其父结点相交度最大的、且未在堆栈中出现的结点设为候选当前可扩展结点,否则继续将栈顶结点出栈。其中:Cur_Idle_Num表示当前搜索过程中已经获的空闲数;Expect_Idle_Num表示还可能增加的空闲数;MaxI_dle_Num表示目前已经找到的、最优序列的空闲单元数;RowNum表示当前搜索序列中,目前前后两侧之间仍然都为空行的数目;以及ElseWidth表示目前未进入堆栈所有项的宽度;当前最优排序设置:在结点入栈过程中,在当前空闲单元数不再增加时,设置Max_Idle_Num=Cur_Idle_Num,依据入栈先后顺序设置当前无关项的最优排序。
无关项合并模块904:对于一个项集合,依据无关项排序模块给出的排序关系,从左到右将所有项逐步合并为一项。
最终待填充项序列生成模块906:在类Ⅱ自身合并阶段,已经生成了相应的待填充项。当类Ⅱ中的项进行无关项排序后,按照这种排序关系生成一个新项T,把封装T在内部的空闲单元也加入相应的待填充项中或生成新的待填充项。然后,将未封闭在T内部的空闲单元也依据位置合并到相应的待填充项中,从而生成最终的待填充项。再将这些待填充项按照其含有未封闭在T内部的空闲单元数目的多少从小到大排序形成最终待填充项序列。
填补关系生成模块908:对于生成的待填补项序列,按照排列的先后顺序采用贪婪式搜索算法、逐个寻找其由类Ⅲ中哪些项组成将使其剩余的空闲空间最少。本发明给出的一种的具体方法如下:
第一步:对于待填补项序列S为空,则结束;
第二步:取待填补项序列S的第一项S1,并将S1从序列中删掉,将其加到结果集中;
第三步:采用贪婪算法、利用包含关系在类Ⅲ中剩余子类序列中搜索最长的项U,使Sj包含U,如果不存在这样的项,跳到第一步;
第四步:S1=S1-U,将U从相应子类中删除,并将U加入到集合Condiate中,如果该子类已经为空,则将该子类从子类序列中删除,执行第三步。
逐项填补模块910:针对类Ⅱ中的每一项T,依据其所包含的待填充项,以及待填充项与类Ⅲ中项的填补关系,将相应的类Ⅲ中项的合并到T中,同时记录类Ⅲ中项在T中的起始位置。
类Ⅲ自身合并模块710,连接到类Ⅱ填补模块708,用于将类Ⅲ中满足合并度大于0的基本项进行合并,且确保合并后占用的列数最少。类Ⅲ中的每一项,可用一个0-1向量来表示,0表示该行上空间空闲,1表示占用。为减少空间,可将这个向量进行压缩,去除0分量,占用情况用所在行号来表示,从而将项用一个集合来表示。
为便于理解本发明给出的方法,引入三个概念:
行全集:求取Ⅲ类中项占用的、所有行的集合;
取反:指依据全集,求得该项未被占用的行,按行数从小到大排列,并用集合的形式表示;
包含:项用集合的形式表示后,一个项包含于另一个项,称之为项包含。
根据本发明的一个实施例的类Ⅲ自身合并过程如下:
第一步:对于类Ⅲ中的所有项,按照项的起始行位置进行分类,这些类之间按照每一类的起始位置从小到大排序,形成子类序列,而在每一类中按照每个项集合中元素数量的多少从大到小排序;
第二步:当子类序列为空时,合并过程结束;否则转入第三步;
第三步:求取当前类Ⅲ中的行全集;
第四步:依据全集,对子类序列中的第一个子类中的所有项取反,形成候选合并集合S,并将第一个子类从子类序列中删除;
第五步:当集合S不为空时,执行第六步,否则跳到第二步;
第六步:取集合S中的项Sj;
第七步:采用贪婪算法、利用包含关系在类Ⅲ中剩余子类序列中搜索搜索最长的项U,使Sj包含U,如果不存在这样的项,跳到第六步;
第八步:Sj=Sj-U,将U从相应子类中删除,如果该子类已经为空,则将该子类从子类序列中删除,执行第九步;
第九步:将Sj对应的项以及所有潜在合并项合并为一个项,并把其加入合并结果序列中,跳到第五步。
返回到图7,无关项排序模块712,连接到类Ⅲ自身合并模块,用于将类Ⅱ、类Ⅲ、类Ⅳ中的所有项进行排序,使得各项按照这种排序合并后,封装在内部的空闲空间数最小,并并录记录基本项之间的合并关系;以及
无关项合并模块714,连接到无关项排序模块,用于按照无关项排序模块给出的排序关系对类Ⅱ、类Ⅲ、类Ⅳ中的项进行合并(参看图11)。
返回到图6,关联值计算模块608,用于依据合并模块606的最终合并结果,计算字典的组成字符在本层的关联值;当TRIE树某一层的所有项合并为一项时,遍历合并项中所有基本项在合并项中的起始位置,设置所在层相应字符的关联值;相应结点的空间占用范围则是此项相应行的占用情况。例如,图13是TRIE中某层结点的最终合并结果,1、2、3代表三个结点,每段颜色对应每个子结点(每个元素)中词的空间占用情况,E1、E2、E3分别对应于三个基本项占用空间的起始位置,即相应元素对应的关联值,L1、L2、L3描述了合并后结点的空间占用范围。对于在简化阶段删除的列,则对应元素的关联值为0。对于删除的行,所对应结点的其空间占用范围等于非空子结点的空间占用范围。以及
空间占用信息上传模块610,用于将本层结点的空间占用情况传给上一层。当某一层的所有项合并为一项时,将项中每一行所对应的空间占用情况传递给此行所对应结点的父结点,并存于相应的子结点分量中。
该系统利用关联值相加可以快速判断一个单词是否属于词典,而且本发明在增加哈希表空间利用率方面进行了设计,降低了词典索引的空间复杂度。由于本发明给出的Hash函数构造方法,内存占用空间在同类索引中相对较小,可将其应用于对速度和空间要求高的应用系统中。
尽管已经描述了本发明的不同实施例,但是对于本领域技术人员来说,在本发明的范围内可能存在更多的实施例和实现方式。根据发明的任何变化和改变均落入权利要求的保护范围。