赞 | 2 |
VIP | 143 |
好人卡 | 1 |
积分 | 1 |
经验 | 216792 |
最后登录 | 2019-10-10 |
在线时间 | 24 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 61
- 在线时间
- 24 小时
- 注册时间
- 2008-8-5
- 帖子
- 1924
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
继 chaochao 之后(http://rpg.blue/forum.php?mod=viewthread&tid=140141)的第二波蛋疼,欢迎各位踊跃参加,参与就有奖励!这次的主题是散列函数!
散列结构是一种十分高效的数据结构,在设计良好的散列函数驱动下,散列结构的各种基本操作都只需要平摊的常量时间内完成。散列元素由其唯一的散列码标识,散列码相同的元素被视为相等元素,不可同时存在于结构中。我们这次的任务就是设计一个计算散列码的散列函数
给你一个包含了两个整数域 x、y 的 Point 结构(设 Point 结构集合为 P),找到一个计算完美散列码(Z 中的一个元素)的散列函数 F:P->Z,使得 F(a) = F(b) 当且仅当 a.x = b.x AND a.y = b.y
所谓完美,是指永远不会出现散列碰撞,即出现两个不同的点(x 不相等或 y 不相等)却生成了相同散列码的情况。该散列函数必须一次性生成无冲突散列码
(注:这里的 = 关系是整数集合 Z 中的 =,相等关系)
Ruby 程序框架:
- class S
- def initialize(a, b)
- @a, @b = a, b
- end
- def eql?(obj)
- return self.hash == obj.hash
- end
- def hash
- #...
- end
- end
复制代码 这里的 hash 方法就是 Point 类的散列函数(方法),我们的目的就是要实现 hash 方法,使得 x 和 y 都相同的 Point 对象在 Ruby 的散列表中被视为相同的键,而不会重复生成元素
演示——
覆盖继承自 Object 的 hash 方法前:
- ret = {}
- ret[Point.new(1, 0)] = 1
- ret[Point.new(2, 3)] = 2
- ret[Point.new(1, 0)] = 3
- ret[Point.new(1, 0)] = 4
- p ret[Point.new(1, 0)] # => nil
- p ret # => 四个点的对象都存在与散列表中,但其实第1、3、4个点是相同的
复制代码 完美实现 hash 方法后:
- ret = {}
- ret[Point.new(1, 0)] = 1
- ret[Point.new(2, 3)] = 2
- ret[Point.new(1, 0)] = 3
- ret[Point.new(1, 0)] = 4
- p ret[Point.new(1, 0)] # => 4
- p ret # => 只包含两个不同的点 (1,0) 和 (2, 3)
复制代码 为了方便在 Ruby 中测试,你可以做如下假设:x 和 y 的值在 15 位整数的表示范围内,即 -16384 到 +16383,这样生成的散列码就是一个 30 位整数,能够被 Fixnum 表示
要求:给出能说明算法的伪代码,或者详细代码
语言不限,重在参与,欢迎提问和讨论 |
|