我正在学习编写抽象数据类型。尝试构建基于dict的自定义哈希表。
到目前为止,我已经创建了一个课程占位符。
public class HashMapDict implements IDict
{
private var _map:Array;
public function HashMapDict()
{
_map = new Array();
//TODO: implement function
}
public function set(keys:Array):Boolean
{
// 1. For each key in array of keys
// 2. Pass Key.key to hash function
// 3. Write Key to _map[hash(Key.key)]
return true;
}
}
我看到主要方法集执行以下操作
// 1. For each key in array of keys
// 2. Pass Key.key to hash function
// 3. Write Key to _map[hash(Key.key)]
我在想的是使用加密库来生成哈希。但我对它应该如何运作有点困惑。例如试图查看像as3crypto(http://crypto.hurlant.com/demo/)这样的几个库,它似乎以一种我认为不能用于数组索引的方式产生哈希。
E.g。
http://screencast.com/t/bE1lYQEqp4D
您能告诉我可以使用哪个lib来生成可用的哈希值吗?他们应该怎么样?
答案 0 :(得分:2)
就像抬头一样 - 我几乎可以保证你不会在Dictionary
甚至Object
做出更好的事情。您提出的计划可行,但它不会带来任何好处。我也觉得有必要建议使用Vector over Array作为向量更快,更强大。
Hash libs的问题在于它们通常会导致非常非常大的数字。例如,MD5将产生一个十六进制字符串,其代表甚至可以适用于uint(uint in,因为它可以适合2 ^ 32,MD5是2 ^ 128)。这也恰好是maximum size of an Array/Vector in AS.
这并不是说它们不能适合Number
(它可以容纳约1.79 * 10 ^ 308),但它确实意味着你将失去数字索引的好处,你肯定那时候Vector不会从中受益。你基本上会回到Object
。
说实话,它确实看起来像你有两种选择之一。您可以使用第二个Array / Vector实现直接查找。这具有O(n)查找时间的问题,而哈希表的查找时间将为O(1)。
至少在我看来,无论做什么,你都需要使用Dictionary
或Object
。
答案 1 :(得分:1)
对于哈希表的实现,加密哈希函数是过度的。
仅当您担心某人尝试向您提供错误数据(例如,包含大量哈希冲突的密钥)的攻击时,才能使哈希表变慢。
对于哈希表的使用,像下面这样的哈希函数就足够了(伪代码,因为我不知道正确的语法):
hash = 0
for c in string:
hash = hash * 13 + c;
return hash
但正如其他答案所说,内置了一个哈希表,你真的不需要重新实现它。
答案 2 :(得分:0)
我可能会遗漏一些东西,但我认为你应该看看flash.utils::Dictionary
它使散列过时。如果你必须拥有某种原始密钥,我建议使用以下内容:
class UIDUtil {
static private var map:Dictionary = new Dictionary(true);
static private var counter:int = 0;
static public function getUID(value:*):int {
return map[value] ||= counter++;
}
}
但是我的课程将实现为:
public class HashMapDict implements IDict {
private var _map:Dictionary = new Dictionary();
public function set(keys:Array):Boolean {
for each (var key:* in keys) _map[key] = key;
return true;
}
}
我不确定它的用途;)