基于内存的散列表的构建方法、文本查找方法及相应装置的制造方法_2

文档序号:8258855阅读:来源:国知局
函数和DEKHash函数。
[0043]示例性的,上述用于确定主散列值对应的散列表入口地址的映射算法,可为质数取余法、平方取中法或折叠法。
[0044]操作130、使用预设的至少一个从散列函数,计算文本数据对应的从散列值,并基于从散列值得到目标散列值。
[0045]在本实施例中,从散列函数也可为上述备选的多个散列函数中的任一散列函数,但是为解决散列冲突的问题,须保证从散列函数与主散列函数不同。也即,主散列函数和从散列函数为BKDRHash函数、APHash函数、DJBHash函数、JSHash函数、RSHash函数、SDBMHash函数、PJWHash函数、ELFHash函数和DEKHash函数中两种不同的散列函数。
[0046]示例性的,使用预设的至少一个从散列函数,计算文本数据对应的从散列值,并基于从散列值得到目标散列值,具体包括:
[0047]分别使用预设的多个从散列函数中的各个从散列函数,计算文本数据对应的从散列值;
[0048]将计算得到的各个从散列值合并在一起,生成目标散列值。
[0049]具体的,为了更好的保证在得到文本数据的主散列值之后,再次得到的目标散列值不会发生冲突,本实施例可将计算得到的各个从散列值拼接在一起,生成一个新的散列串,作为目标散列值。
[0050]当然,本领域普通技术人员应理解,本实施例也可以仅使用预设的一个从散列函数,计算文本数据对应的从散列值,并将该从散列值作为目标散列值。
[0051]操作140、将目标散列值存储至内存中与散列表入口地址对应的单向链表,以构建散列表。
[0052]示例性的,将目标散列值存储至内存中散列表入口地址指向的单向链表,具体包括:判断内存中散列表入口地址处,是否存储有用于指向与散列表入口地址对应的单向链表的表头指针;如果是,则在单向链表的队尾插入一个新节点,将目标散列值存储至新节点中的信息域;如果否,则创建用于指向与散列表入口地址对应的单向链表的表头指针,存储至散列表入口地址处,并在内存中的所述表头指针指向的存储位置处,创建单向链表的第一个节点,将目标散列值存储至第一个节点中的信息域。
[0053]在上述示例中,当判断内存中散列表入口地址处,存储有用于指向与散列表入口地址对应的单向链表的表头指针时,则会识别到发生了散列冲突。
[0054]在本实施例中,在使用一种散列函数,计算得到文本数据对应的散列值,并对该散列值进行再散列得到散列表入口地址之后,并不是如传统的链地址法那样直接将文本数据本身存储至内存中该散列表入口地址对应的单向链表,而是针对传统的链地址法作了如下改进:使用另外一些散列函数计算文本数据对应的其他散列值,并基于得到的其他散列值生成目标散列值,进而将目标散列值存储至内存中该散列表入口地址对应的单向链表,以构建散列表。由于散列技术具备如下特性:通过散列函数得到的散列值的长度要小于文本数据的长度,因此本实施例提供的技术方案,不仅能够解决散列冲突的问题,而且所构建的散列表占用的内存更少,节约了内存资源。
[0055]实施例二
[0056]图2A是本发明实施例二提供的一种基于内存的散列表的构建方法的流程示意图。本实施例在上述实施例一的基础上,提供一种优选实施例。本实施例提供的基于内存的散列表的构建方法,可以是在主频为2.2GHz的intel core i7CPU、内存为32GB的硬件环境和基于Visual C++的开发环境的windows2008server系统下进行的。参见图2A,本实施例提供的基于内存的散列表的构建方法具体包括如下操作:
[0057]操作210、判断预设的数据集中是否存在未获取的用于查找的文本数据。如果是,执行操作220,否则结束流程。
[0058]操作220、从数据集中获取一条用于查找的文本数据。执行操作230。
[0059]操作230、使用预设的主散列函数,计算本次获取的文本数据对应的主散列值,并根据质数取余法确定主散列值对应的散列表入口地址。执行操作240。
[0060]示例性的,本实施例中的主散列函数可优选为均匀散列性能较为优秀的BKDRHash函数。
[0061]根据质数取余法确定主散列值对应的散列表入口地址,具体为:将主散列值与预设值进行取模运算,得到主散列值对应的散列表入口地址。其中,预设值可为一个质数,该质数大于预设的数据集中用于查找的文本数据的条数(也即文本数据长度),小于散列表桶数量(也即散列表长度)。
[0062]操作240、判断内存中散列表入口地址处,是否存储有用于指向与散列表入口地址对应的单向链表的表头指针。如果是,执行操作250,否则执行操作260。
[0063]操作250、在单向链表的队尾插入一个新节点,作为当前节点。执行操作280。
[0064]操作260、创建用于指向与散列表入口地址对应的单向链表的表头指针,存储至散列表入口地址处。执行操作270。
[0065]操作270、在内存中的所述表头指针指向的存储位置处,创建单向链表的第一个节点,作为当前节点。执行操作280。
[0066]操作280、分别使用预设的两个从散列函数,计算本次获取的文本数据对应的从散列值,并将计算得到的两个从散列值合并在一起,生成目标散列值。执行操作290。
[0067]操作290、将目标散列值存储至当前节点中的信息域。返回操作210,继续执行。
[0068]本实施例的一个关键点在于,两条文本数据的不同散列结果同时冲突的几率是非常低的,例如有测试结果证明,使用业界著名的BKDRHash函数,对100000个无意义字母和数字组成的随机串散列后,散列值冲突为2个,对100000个有意义英文句子的散列值冲突为O个。当不同的文本数据在散列表中的散列表入口地址冲突时,会进入此散列表入口地址对应的单向链表,只要保证在该单向链表内不同条文本数据的目标散列值不冲突即可唯一区分各条文本数据。而在散列表的长度为大于文本数据长度的素数,且主散列函数是比较均匀分布的情况下,同一个散列表入口内地址对应的单向链表长度一般较短。所以,一般使用一个不同于主散列函数的从散列函数来得到目标散列值,基本可以保证单向链表内不同文本数据的目标散列值不发生冲突,而本实施例使用两个不同散列函数,则能够更好的避免散列冲突的发生。
[0069]例如,即使以BKDRHash的实验结果中的随机串为例,假设单向链表的长度为100,那么在单向链表内使用单个散列函数发生散列冲突的几率为(2/100000) *100 = 1/500,而使用两个不同散列函数发生散列冲突几率为1/250000。所以,在本实施例中采用两个不同的优秀散列函数是可以满足不冲突要求的,当然也可以通过进一步通过增加从散列函数的方法来进一步降低散列冲突概率。
[0070]图2B是本发明实施例二提供的一种在内存中构建的散列表的结构示意图。参见图2B,预设的文本集201中包括6条用于查找的文本数据:“A”、“B”、“C”、“D”、“E”和“F”(此处仅作为示例加以说明,在实际当中,每条用于查找的文本数据会由多个字符串组成),散列表202的长度为7,散列表入口地址分别为0-6。
[0071]使用主散列函数,分别对“A”、“C”和“F”进行散列之后,得到的主散列值相同,进而会得到相同的散列表入口地址“1”,内存中散列表入口地址“I”处存储有用于指向与散列表入口地址“ I ”对应的单向链表的表头指针F (I),在该单向链表中,共有三个节点:
[0072]第一个节点,第一个节点的信息域中存储有使用“A”对应的目标散列值,该目标散列值由使用第一个从散列函数H2对“A”进行散列得到的第一从散列值H2 (A)和使用第二个从散列函数H3对“A”进行散列得到的第二从散列值H3 (A)拼接而成;
[0073]第二个节点,第二个节点的信息域中存储有使用“C
当前第2页1 2 3 4 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1