移位折叠散列以生成数据库中记录的索引
shift fold hashing to generate indices of records in database
我正在做一项作业,我被要求实现一个 shift fold 函数来散列数据库中记录的 String 类型键,并 return 确定该记录在数据库中的位置。据我了解,这意味着 sfold 函数必须生成与该记录在数据库中的位置相匹配的散列。
方法代码如下:
public static long sfold(String s, int M) {
int intLength = s.length() / 4;
long sum = 0;
for (int j = 0; j < intLength; j++) {
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++) {
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++) {
sum += c[k] * mult;
mult *= 256;
}
return (Math.abs(sum) % M);
}
这会生成一个介于 0 和记录数 - 1 (M-1) 之间的随机数字。问题是数字不是唯一的,可能不会生成所有可能的数字。那么如何使用它来return记录在数据库中的位置呢?
我的想法是从字符串键生成散列,获取散列数字,按该数字对记录进行排序,然后将它们插入数据库,但就像我说的那样,该方法不会产生唯一数字并且无法保证获取所有数字。
“缺乏唯一性”称为碰撞,有不同的解决方法。细节在维基百科中有很好的解释:https://en.wikipedia.org/wiki/Hash_table#Collision_resolution
主要有两种方法:
单独链接使用额外的存储空间 space:如果字符串散列为 table 中已有的数字,它会溢出到辅助存储空间 space。在 in-memory 数据结构中,额外的存储空间通常是链表。
Open addressing 查找未使用的 space:如果字符串散列为 table 中已有的数字,则它存储在同一个 [=46] 中的其他地方=], 根据您事先决定的策略。
你的问题很严重:
mult *= 256;
乘以 2 的幂意味着您将丢弃信息:仅在 8 个字符 mult = 0 之后您将忽略字符串的其余部分。将乘数更改为质数,例如 127,即可解决此问题。
你这里还有一个问题:
return (Math.abs(sum) % M);
Math.abs
有一个特殊情况,它不是 return 正数:Long.MIN_VALUE。解决它的一种方法是在 之后取绝对值 余数:
return Math.abs(sum % M);
我正在做一项作业,我被要求实现一个 shift fold 函数来散列数据库中记录的 String 类型键,并 return 确定该记录在数据库中的位置。据我了解,这意味着 sfold 函数必须生成与该记录在数据库中的位置相匹配的散列。
方法代码如下:
public static long sfold(String s, int M) {
int intLength = s.length() / 4;
long sum = 0;
for (int j = 0; j < intLength; j++) {
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++) {
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++) {
sum += c[k] * mult;
mult *= 256;
}
return (Math.abs(sum) % M);
}
这会生成一个介于 0 和记录数 - 1 (M-1) 之间的随机数字。问题是数字不是唯一的,可能不会生成所有可能的数字。那么如何使用它来return记录在数据库中的位置呢?
我的想法是从字符串键生成散列,获取散列数字,按该数字对记录进行排序,然后将它们插入数据库,但就像我说的那样,该方法不会产生唯一数字并且无法保证获取所有数字。
“缺乏唯一性”称为碰撞,有不同的解决方法。细节在维基百科中有很好的解释:https://en.wikipedia.org/wiki/Hash_table#Collision_resolution
主要有两种方法:
单独链接使用额外的存储空间 space:如果字符串散列为 table 中已有的数字,它会溢出到辅助存储空间 space。在 in-memory 数据结构中,额外的存储空间通常是链表。
Open addressing 查找未使用的 space:如果字符串散列为 table 中已有的数字,则它存储在同一个 [=46] 中的其他地方=], 根据您事先决定的策略。
你的问题很严重:
mult *= 256;
乘以 2 的幂意味着您将丢弃信息:仅在 8 个字符 mult = 0 之后您将忽略字符串的其余部分。将乘数更改为质数,例如 127,即可解决此问题。
你这里还有一个问题:
return (Math.abs(sum) % M);
Math.abs
有一个特殊情况,它不是 return 正数:Long.MIN_VALUE。解决它的一种方法是在 之后取绝对值 余数:
return Math.abs(sum % M);