本发明涉及计算机数据处理技术领域,具体为适用于存储空间受限的设备的通讯录防重构建方法。
背景技术:
现有技术中,对于通讯录的处理,在数据存储时,大多是不做防重处理,而是在后续的计算的时候,对参与计算的通讯录数据做防重处理。但是,在基于如单片机等存储空间有限的设备上进行开发的时候,在存储的时候,就需要进行防重处理,但是现有的防重方法大多针对存储空间不受限的设备进行设计的,其对存储空间的使用方式,不适用于存储空间有限的设备,在单片机等存储空间有限的设备上应用的时候,会导致运行效率变差。
技术实现要素:
为了解决现有的通讯录防重方法运行于存储空间有限的设备上会发生运行效率变差的问题,本发明提供适用于存储空间受限的设备的通讯录防重构建方法,其可以在有限的内存中高效率运行,且算法简单易懂,易于实现。
本发明的技术方案是这样的:适用于存储空间受限的设备的通讯录防重构建方法,其特征在于,其包括以下步骤:
s1:把所有的需要添加的通讯录数据读入设备的内存中;
s2:根据所述通讯录数据中包含数据种类n_class,确定需要建立通讯录哈希表的数量n_directory;每一个所述通讯录哈希表中以其对应种类的数据作为关键码,所述关键码以外的数据作为关联数据、以关联数据地址的形式存储在该表中;
即:n_class等于n_directory,且n_directory、n_class都为正整数;
s3:构建n_directory个所述通讯录哈希表;
在每一个所述通讯录哈希表中,每一行的列元素包括:占用标志、数据域、链索引;
所述占用标志的字段用来设置使用标志,表示该记录是否已经被使用;
所述数据域的字段用来存放实际数据,所述实际数据包括:关键码数据字段、关联数据地址字段;
所述关联数据地址字段存储了在另外的关联通讯录哈希表中的索引地址,该索引地址存储了与所述关键码设置了索引关系的其他种类的数据;
所述关键码为联系人姓名的所述通讯录哈希表设置为主表,其他种类的所述通讯录哈希表设置为从表;
在所述主表中,所述关键码数据字段和所述关联数据地址字段的数量关系为:1:num,其中num为自然数,且num≥(n_class-1);所述主表中的所述关联数据地址字段中,保存了所述关键码以外的其他所有种类的关联数据的索引信息,其中同一种类的所述关联数据地址字段的数量大于等于1;
在所述从表中,所述关键码数据字段和所述关联数据地址字段的数量关系为:1:1;所述从表中的所述关联数据地址字段中,只保存所述主表的关键码的地址;
所述链索引的字段用来支撑拉链法处理冲突,当多条信息需占用同一记录位置时,该字段用来记录下一条记录的索引;
s4:初始化所述通讯录哈希表长度为n+n*y%;
其中,n为哈希表的基本容量,n为正整数;
y用于处理哈希映射冲突的空间预留率,y为正整数;当新增数据时,如果计算得到索引对应的数据与新增数据发生冲突,需要在基本容量n的后面顺序的挂接一个冲突链,用来放置发生冲突的联系人信息,此时就会使用到基本容量以外的n*y%的空间来构建冲突链;
s5:初始化所有的n_directory个所述通讯录哈希表的字段;
将每个所述通讯录哈希表的所述占用标志字段设置为:未使用;
将所有的所述链索引字段设置为:无效;
将所有关键码对应的所述关联数据地址字段的使用状态都初始化为:无效;
s6:获取步骤s1中读入所有的需要添加的所述通讯录数据,依次读取每一条通讯录数据,赋值给待处理通讯录数据directorydata;
所述待处理通讯录数据directorydata包括:关键码数据keycode、关联数据linkcode;其中,所述关键码数据keycode和所述关联数据linkcode的数量关系为:1:n_data,其中n_data为自然数;
根据所述待处理通讯录数据directorydata中关键码数据keycode的种类,其对应种类的通讯录哈希表作为待处理通讯录哈希表targetdirectory;
s7:添加所述待处理通讯录数据directorydata到所述待处理通讯录哈希表targetdirectory中;
具体包括以下步骤:
a1:将所述关键码数据keycode赋值给待处理关键码tempkeycode;使用哈希算法计算所述待处理关键码tempkeycode的哈希码,假设得到哈希码的值为hashcode;
a2:计算所述待处理关键码tempkeycode的所述链索引;
使用哈希码的值hashcode模上n,得到余数index,index即为所述链索引字段的值,具体如下:
index=hashcodemodn;
a3:在所述待处理通讯录哈希表targetdirectory中,检查index处的行中对应的所述占用标志位;
如果所述占用标志位的字段为:未使用,则表示其对应的所述数据域中的关键码数据字段没有被使用,则index对应的行设置为待插入行元素,执行步骤a6;
否则,则表示其对应的所述数据域中的关键码数据字段已经被使用,执行步骤a4;
a4:取得所述数据域中的关键码数据字段中的数据,作为对比数据comparecode与所述待处理关键码tempkeycode进行比较;
如果comparecode与tempkeycode相同,则表示所述待处理关键码tempkeycode已经存在于哈希表中,不需要再次添加,本次针对待处理关键码tempkeycode的添加操作结束;
否则,表示所述待处理关键码tempkeycode在哈希表中没有被存储过,不存在数据重复问题,执行步骤a5;
a5:从所述待处理通讯录哈希表targetdirectory的基本容量n后面的n*y%区域中顺序的搜索第一个数据域未被占用的行作设置为待插入行元素,挂接在所述冲突链的末尾,且把所述冲突链尾部最后一行的索引的值赋值给index;
a6:将所述待处理关键码tempkeycode,存入所述待插入行元素中所述数据域中的关键码数据的字段中,其对应的所述链索引自动中存储index的值;
s8:针对所述待处理关键码tempkeycode,在同一条所述待处理通讯录数据directorydata中找到对应的所述关联数据linkcode,设置所述待处理关键码tempkeycode与所述关联数据linkcode的相互的索引关系:
s9:重复步骤s6~s8,直至步骤s1中读入的所有的所述通讯录数据都处理完毕,结束本次构建操作。
其进一步特征在于:
步骤s8中,设置所述待处理关键码tempkeycode与所述关联数据linkcode的相互的索引关系,包括如下步骤:
b1:在所述待处理通讯录数据directorydata中,确认所述待处理关键码tempkeycode的所述关联数据linkcode的数量n_data;
如果n_data=0,则代表所述关联数据linkcode为空,不需要进行关联索引操作,本次关联索引的操作结束;
否则,执行步骤b2;
b2:确认所述待处理关键码tempkeycode的种类;
如果所述待处理关键码tempkeycode的种类为联系人姓名,则执行步骤b3;
否则,执行步骤b7;
b3:在n_data个所述关联数据linkcode中顺序的依次取出每一个数据,依次设置为待确认关联数据templinkcode;
b4:所述待处理关键码tempkeycode为主键、其对应的所述待处理通讯录哈希表targetdirectory为主表,所述待确认关联数据templinkcode为从键、其对应的通讯录哈希表为从表;
调用步骤s7,把取出的所述待确认关联数据templinkcode按照其种类插入到其对应种类的所述从表中,且记录其在所述从表的索引地址为templinkaddress;
b5:带入index作为所述主键在所述主表中的索引地址、templinkaddress作为所述从键在所述从表中索引地址,顺序执行以下步骤:
在所述从表中建立所述主键和所述从键的索引关系;
在所述主表中建立所述从键和所述主键的索引关系;
b6:重复b4~b5,直至n_data个所述关联数据linkcode都被查找完毕;执行步骤b9;
b7:所述待处理关键码tempkeycode为从键、其对应的所述待处理通讯录哈希表targetdirectory为从表,所述关联数据linkcode为主键、其对应的通讯录哈希表为主表;
所述关联数据linkcode待确认关联数据templinkcode;
调用步骤s7,把所述待确认关联数据templinkcode插入到所述主表中,且记录其在所述主表的索引地址为templinkaddress;
b8:带入templinkaddress作为所述主键在所述主表中的索引地址、index作为所述从表在所述从表中的索引地址,顺序执行以下步骤:
在所述主表中,建立所述从键和所述主键的索引关系;
在所述从表中,建立所述主键和所述从键的索引关系;
b9:本次关联索引的操作结束;
在所述从表中,建立所述主键和所述从键的索引关系,包括如下步骤:
c1:在所述从表中,所述从键对应的所述关联数据地址字段设置为从键关联地址字段;
c2:确认所述从键关联数据地址字段的状态;
如果所述从键关联数据地址字段的状态为:无效,代表所述从键在所述从表中,没有与所述主表中的关键码建立过关联索引,则将所述主键在所述主表中的索引地址存入到所述从键关联数据地址字段中;
执行步骤c4;
否则,代表所述从键在其对应的所述从表中,已经与所述主表中的关键码建立过关联索引,则执行步骤c3;
c3:向用户确认是否要重新建立索引关系;
如果需要重新建立索引关系,则删除现有索引关系,执行步骤c4;
否则执行步骤c5;
c4:在主表中,建立所述从键与所述主键的索引关系;
c5:本次操作结束;
在所述主表中,建立所述从键和所述主键到的索引关系:
d1:在所述主表中,设所述主键对应的关联数据地址字段设置为主键关联数据地址字段;
顺序获取所述主键对应的num个所述主键关联数据地址字段的状态;
d2:确认每一个所述主键关联数据地址字段的状态;
如果所有的所述主键关联数据地址字段的状态都不是无效,则代表所有的所述主键关联数据地址字段都被使用,执行步骤d4;
否则,找到第一个状态为无效的所述主键关联数据地址字段时,停止确认所述主键关联数据地址字段的状态的操作,执行步骤d3;
d3:将所述从键在所述从表中的索引地址存入到此字段中,本次操作结束;
d4:提示用户无法针对所述主键继续添加所述从键,询问客户是否要对所述主键的关联数据进行删除;
如果客户选择是,进入所述主键的管理数据删除流程,本次操作结束;
如果客户选择否,本次操作结束;
步骤c3中,具体包括如下步骤:
e1:显示提示信息:该所述从键已经属于其他主键,询问用户是否要修改该从键的关联主键;
如果用户选择:是,则执行步骤e2;
如果用户选择:否,则执行步骤e4;
e2:获取当前所述从键有索引关系的主键,设置为待解除主键;在所述主表中找到所述待解除主键;
e3:在所述待解除主键对应的关联数据地址字段中,检索到所述从键对应的关联数据地址字段,且把其状态设置为:无效;
e4:本次操作结束;
所述通讯录基础哈希表的结构通过数组实现;
所述通讯录数据中包含数据种类n_class的值为2,所述数据种类包括:联系人姓名、电话号码;所述通讯录哈希表的个数n_directory为2,所述通讯录哈希表包括联系人姓名哈希表、电话号码哈希表;
所述联系人姓名哈希表中,设哈希表中预计存储的所述用户行为个数为x,则所述联系人姓名哈希表的数组元素数量为m:
m=(1+x%)*x
式中:x为根据产品使用环境预设的新增联系人预留率;针对所述联系人姓名哈希表,所述联系人姓名哈希表数组元素数量为m即为其基本容量n;
与所述联系人姓名哈希表对应的所述电话号码哈希表中,所述电话号码哈希表的数组元素量p符合下面的公式:
p=m*p
式中:m为所述联系人姓名哈希表的长度,p为一个联系人可拥有电话的最大数量;针对所述电话号码哈希表,所述电话号码哈希表的数组元素量p即为其基本容量n;
所述空间预留率y%的取值范围为:20%≤y%≤30%。
本发明提供的适用于存储空间受限的设备的通讯录防重构建方法,其并非基于数据库的去除重复数据,而是在构建数据表的时候,在内存中对数据进行防重处理。现有的基于数据库的防重算法,其算法复杂度计算方式为:通讯录中存在电话和姓名两种数据,先将通讯录取出,然后依次取出一个电话与剩下的电话对比,看是否重复,需要
附图说明
图1为本发明中的哈希表的基本结构的示意图;
图2为双哈希表数据域结构及互相的索引关联结构示意图;
图3为本发明中哈希表构建的流程示意图;
图4为哈希表之间关联索引的流程示意图。
具体实施方式
如图1所示,本发明适用于存储空间受限的设备的通讯录防重构建方法,其包括以下步骤。
s1:把所有的需要添加的通讯录数据读入设备的内存中,在内存中完成下述计算。
s2:根据通讯录数据中包含数据种类n_class,确定需要建立通讯录哈希表的数量n_directory;每一个通讯录哈希表中以其对应种类的数据作为关键码,关键码以外的数据作为关联数据、以关联数据地址的形式存储在该表中;图1~图2所示的实施例中,通讯录数据中包含数据种类n_class的值为2,数据种类包括:联系人姓名、电话号码。
s3:构建n_directory个通讯录哈希表;通讯录哈希表的个数n_directory为2,通讯录哈希表包括联系人姓名哈希表、电话号码哈希表;
如图1所示,在每一个通讯录哈希表中,每一行的列元素包括:占用标志、数据域、链索引;
占用标志的字段用来设置使用标志,表示该记录是否已经被使用;
数据域的字段用来存放实际数据,由被存储的实际数据的关键码数据字段、关联数据地址字段构成;
关联数据地址字段存储了在另外的关联通讯录哈希表中的索引地址,该索引地址存储了与关键码数据字段设置了索引关系的其他种类的数据;
关键码为联系人姓名的通讯录哈希表设置为主表,其他种类的通讯录哈希表设置为从表;
在主表中,关键码数据字段和关联数据地址字段的数量关系为:1:num,其中num为自然数,且num≥(n_class-1);主表中的关联数据地址字段中,保存了关键码以外的其他所有种类的关联数据的索引信息,其中同一种类的关联数据地址字段的数量大于等于1;
在从表中,关键码数据字段和关联数据地址字段的数量关系为:1:1;从表中的关联数据地址字段中,只保存主表的关键码的地址;
链索引的字段用来支撑拉链法处理冲突,当多条信息需占用同一记录位置时,该字段用来记录下一条记录的索引。
s4:初始化通讯录哈希表长度为n+n*y%;
其中,n为哈希表的基本容量,n为正整数;
y用于处理哈希映射冲突的空间预留率,y为正整数;当新增数据时,如果计算得到索引对应的数据与新增数据发生冲突,需要在基本容量n的后面顺序的挂接一个冲突链,用来放置发生冲突的联系人信息,此时就会使用到基本容量以外的n*y%的空间来构建冲突链;
实施例中,通讯录基础哈希表的结构通过数组实现;联系人姓名哈希表中,设哈希表中预计存储的用户行为个数为x,则联系人姓名哈希表的数组元素数量为m:
m=(1+x%)*x
式中:x为根据产品使用环境预设的新增联系人预留率;针对联系人姓名哈希表,联系人姓名哈希表数组元素数量为m即为其基本容量n;
与联系人姓名哈希表对应的电话号码哈希表中,电话号码哈希表的数组元素量p符合下面的公式:
p=m*p
式中:m为联系人姓名哈希表的长度,p为一个联系人可拥有电话的最大数量;针对电话号码哈希表,电话号码哈希表的数组元素量p即为其基本容量n;
空间预留率y%的取值范围为:20%≤y%≤30%。
s5:初始化所有的n_directory个通讯录哈希表的字段;
将每个通讯录哈希表的占用标志字段设置为:未使用;
将所有的链索引字段设置为:无效;
将所有关键码对应的关联数据地址字段的使用状态都初始化为:无效;
s6:获取步骤s1中读入所有的需要添加的通讯录数据,依次读取每一条通讯录数据,赋值给待处理通讯录数据directorydata;
待处理通讯录数据directorydata包括:关键码数据keycode、关联数据linkcode;其中,关键码数据keycode和关联数据linkcode的数量关系为:1:n_data,其中n_data为自然数;
根据待处理通讯录数据directorydata中关键码数据keycode的种类,其对应种类的通讯录哈希表作为待处理通讯录哈希表targetdirectory;
s7:添加待处理通讯录数据directorydata到待处理通讯录哈希表targetdirectory中;
具体包括以下步骤:
a1:将关键码数据keycode赋值给待处理关键码tempkeycode;使用哈希算法计算待处理关键码tempkeycode的哈希码,假设得到哈希码的值为hashcode;
a2:计算待处理关键码tempkeycode的链索引;
使用哈希码的值hashcode模上n,得到余数index,index即为链索引字段的值,具体如下:
index=hashcodemodn;
a3:在待处理通讯录哈希表targetdirectory中,检查index处的行中对应的占用标志位;
如果占用标志位的字段为:未使用,则表示其对应的数据域中的关键码数据字段没有被使用,则index对应的行设置为待插入行元素,执行步骤a6;
否则,表示则表示其对应的数据域中的关键码数据字段已经被使用,执行步骤a4;
a4:取得数据域中的关键码数据字段中的数据,作为对比数据comparecode与待处理关键码tempkeycode进行比较;
如果comparecode与tempkeycode相同,则表示待处理关键码tempkeycode已经存在于哈希表中,不需要再次添加,本次针对待处理关键码tempkeycode的添加操作结束;
否则,表示待处理关键码tempkeycode在哈希表中没有被存储过,不存在数据重复问题,执行步骤a5;
a5:从待处理通讯录哈希表targetdirectory的基本容量n后面的n*y%区域中顺序的搜索第一个数据域未被占用的行作设置为待插入行元素,挂接在冲突链的末尾,且把冲突链尾部最后一行的索引的值赋值给index;
a6:将待处理关键码tempkeycode,存入待插入行元素中数据域中的关键码数据的字段中,其对应的链索引自动中存储index的值;
s8:针对待处理关键码tempkeycode,在同一条待处理通讯录数据directorydata中找到对应的关联数据linkcode,设置待处理关键码tempkeycode与关联数据linkcode的相互的索引关系:
s9:重复步骤s6~s8,直至步骤s1中读入的所有的通讯录数据都处理完毕,结束本次构建操作。
主表和从表构成的双哈希表结构,联系人姓名与其关联数据通过互相索引形成关联,即标志了联系人信息,又为数据结构的维护提供了便利,简化了算法设计,提高了性能。通讯录数据可以存在数据库和文件中,维护时从数据库表中、或文件中读出,通过哈希表结构在内存中进行数据计算,更适用于单片机等存储空间较少、结构简单的设备。
如图4所示,步骤s8中,设置待处理关键码tempkeycode与关联数据linkcode的相互的索引关系,包括如下步骤:
b1:在待处理通讯录数据directorydata中,确认待处理关键码tempkeycode的关联数据linkcode的数量n_data;
如果n_data=0,则代表关联数据linkcode为空,不需要进行关联索引操作,本次关联索引的操作结束;
否则,执行步骤b2;
b2:确认待处理关键码tempkeycode的种类;
如果待处理关键码tempkeycode的种类为联系人姓名,则执行步骤b3;
否则,执行步骤b7;
b3:在n_data个关联数据linkcode中顺序的依次取出每一个数据,依次设置为待确认关联数据templinkcode;
b4:设待处理关键码tempkeycode为主键、其对应的待处理通讯录哈希表targetdirectory为主表,待确认关联数据templinkcode为从键、其对应的通讯录哈希表为从表;
调用步骤s7,把取出的待确认关联数据templinkcode按照其种类插入到其对应种类的从表中,且记录其在从表的索引地址为templinkaddress;
b5:带入index作为主键在表中的索引地址、templinkaddress作为从键在从表中索引地址,顺序执行以下步骤:
在从表中建立主键和从键的索引关系;
在主表中建立从键和主键的索引关系;
b6:重复b4~b5,直至n_data个关联数据linkcode都被查找完毕;执行步骤b9;
b7:设待处理关键码tempkeycode为从键、其对应的待处理通讯录哈希表targetdirectory为从表,关联数据linkcode为主键、其对应的通讯录哈希表为主表;
关联数据linkcode待确认关联数据templinkcode;
调用步骤s7,把待确认关联数据templinkcode插入到主表中,且记录其在主表的索引地址为templinkaddress;
b8:带入templinkaddress作为主键在主表中的索引地址、index作为从表在从表中的索引地址,顺序执行以下步骤:
在主表中,建立从键和主键的索引关系;
在从表中,建立主键和从键的索引关系;
b9:本次关联索引的操作结束。
在从表中,建立主键和从键的索引关系,包括如下步骤:
c1:在从表中,从键对应的关联数据地址字段设置为从键关联地址字段;
c2:确认从键关联数据地址字段的状态;
如果从键关联数据地址字段的状态为:无效,代表从键在从表中,没有与主表中的关键码建立过关联索引,则将主键在主表中的索引地址存入到从键关联数据地址字段中;
执行步骤c4;
否则,代表从键在其对应的从表中,已经与主表中的关键码建立过关联索引,则执行步骤c3;
c3:向用户确认是否要重新建立索引关系;
如果需要重新建立索引关系,则删除现有索引关系,执行步骤c4;
否则执行步骤c5;
c4:在主表中,建立从键与主键的索引关系;
c5:本次操作结束。
在主表中,建立从键和主键到的索引关系:
d1:在主表中,设主键对应的关联数据地址字段设置为主键关联数据地址字段;
顺序获取主键对应的num个主键关联数据地址字段的状态;
d2:确认每一个主键关联数据地址字段的状态;
如果所有的主键关联数据地址字段的状态都不是无效,则代表所有的主键关联数据地址字段都被使用,执行步骤d4;
否则,找到第一个状态为无效的主键关联数据地址字段;停止确认主键关联数据地址字段的状态;
d3:将从键在从表中的索引地址存入到此字段中,本次操作结束;
d4:提示用户无法针对主键继续添加从键,询问客户是否要对主键的关联数据进行删除;
如果客户选择是,进入主键的管理数据删除流程,本次操作结束;
如果客户选择否,本次操作结束。
步骤c3中,具体包括如下步骤:
e1:显示提示信息:该从键已经属于其他主键,询问用户是否要修改该从键的关联主键;
如果用户选择:是,则执行步骤e2;
如果用户选择:否,则执行步骤e4;
e2:获取当前从键有索引关系的主键,设置为待解除主键;在主表中找到待解除主键;
e3:在待解除主键对应的关联数据地址字段中,检索到从键对应的关联数据地址字段,且把其状态设置为:无效;
e4:本次操作结束。
本发明的技术方案,结构简单,使用存储空间较小,在内存中维护通讯录信息,适用于单片机等低存储设备的计算需求;在加入新的数据时就检测重复,添加新数据的同时完成了查重功能,不但节省了计算时间,而且在后续计算时不必进行查重,降低了后续操作的复杂性。