设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 14545|回复: 41
打印 上一主题 下一主题

[胡扯] 蛋疼数学程序帝!散列算法

 关闭 [复制链接]

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
跳转到指定楼层
1
发表于 2010-8-27 11:11:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

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 程序框架:

  1. class S
  2.   def initialize(a, b)
  3.     @a, @b = a, b
  4.   end
  5.   def eql?(obj)
  6.     return self.hash == obj.hash
  7.   end
  8.   def hash
  9.     #...
  10.   end
  11. end
复制代码
这里的 hash 方法就是 Point 类的散列函数(方法),我们的目的就是要实现 hash 方法,使得 x 和 y 都相同的 Point 对象在 Ruby 的散列表中被视为相同的键,而不会重复生成元素
演示——
覆盖继承自 Object 的 hash 方法前:

  1. ret = {}
  2. ret[Point.new(1, 0)] = 1
  3. ret[Point.new(2, 3)] = 2
  4. ret[Point.new(1, 0)] = 3
  5. ret[Point.new(1, 0)] = 4
  6. p ret[Point.new(1, 0)]  # => nil
  7. p ret                   # => 四个点的对象都存在与散列表中,但其实第1、3、4个点是相同的
复制代码
完美实现 hash 方法后:

  1. ret = {}
  2. ret[Point.new(1, 0)] = 1
  3. ret[Point.new(2, 3)] = 2
  4. ret[Point.new(1, 0)] = 3
  5. ret[Point.new(1, 0)] = 4
  6. p ret[Point.new(1, 0)]  # => 4
  7. p ret                   # => 只包含两个不同的点 (1,0) 和 (2, 3)
复制代码
为了方便在 Ruby 中测试,你可以做如下假设:x 和 y 的值在 15 位整数的表示范围内,即 -16384 到 +16383,这样生成的散列码就是一个 30 位整数,能够被 Fixnum 表示

要求:给出能说明算法的伪代码,或者详细代码
语言不限,重在参与,欢迎提问和讨论

Lv1.梦旅人

梦石
0
星屑
50
在线时间
349 小时
注册时间
2010-6-27
帖子
1264
2
发表于 2010-8-27 11:15:08 | 只看该作者
完全看不懂的表示很有压力。
RTP素材修改教程,教你修改出属于自己的默认素材动画~
http://rpg.blue/forum.php?m ... d=158378&extra=
欢迎来水(雾
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
283
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

3
发表于 2010-8-27 11:21:12 | 只看该作者
就是说给定一组 (x, y) ,在 x y 都相等的情况下,值才相等,对么??

点评

对,“当且仅当”()的关系  发表于 2010-8-27 13:03

《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
4
发表于 2010-8-27 11:22:16 | 只看该作者
一向是以模一个大质数为Hash值,碰撞时做成一个链表
完美哈希还真没想过……
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
283
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

5
发表于 2010-8-27 11:41:52 | 只看该作者
本帖最后由 月兔铃仙 于 2010-8-27 11:55 编辑
  1. #include "md5.h"
  2. #include <iostream>

  3. using namespace std;

  4. void PrintMD5(const char* &str, MD5& md5) {
  5.   cout << "MD5(\"" << str << "\") = " << md5.toString() << endl;
  6. }

  7. int main(int argc, char* argv[]) {

  8.         MD5 md5;
  9.         md5.update("12");
  10.         PrintMD5("", md5);

  11.         md5.update("21");
  12.         PrintMD5("21", md5);

  13.         return 0;
  14.        
  15. }
复制代码
按照 MD5 的定义应该可以,只是可能结果的长度太长了点~~~

-------------------------

Wndows 下无编译器,测试不能,Linux 下不会输出,悲剧~~~~

点评

这是作弊OTL,那还有SHA-1呢口胡!!  发表于 2010-8-28 12:21
MD5 是可以的,但是也自己想一个算法嘛~  发表于 2010-8-27 13:15

评分

参与人数 1星屑 +120 收起 理由
紫苏 + 120

查看全部评分


《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1185
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

6
发表于 2010-8-27 11:58:21 | 只看该作者
本帖最后由 DeathKing 于 2010-8-27 12:07 编辑

看得不是很明白,说的不知道是不是这个意思:

1、映射GET_HASH:P->Z是一个1对1的函数
2、对于e∈P,GET_HASH(e)是e的唯一标识符?(也就是唯一的全局识别id?)

也就是Point.new(1,0)就像1、2那样,是个固定数,也不像Float那样,每次生成的虽然值一样,但是对象却不一样?

点评

补充:对象仍然是不同的,但是交给散列表处理时散列表会认为是相同的元素(即散列集合里的相同元素)  发表于 2010-8-27 13:09
1、基本上可以理解为双射;2、是的,但此处要指定论域为 P;最后一个问题:是的,Point.new(1, 0).eql?(Point.new(1,0)) 应该返回 true  发表于 2010-8-27 13:08

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv1.梦旅人

有事烧纸

梦石
0
星屑
154
在线时间
509 小时
注册时间
2005-10-22
帖子
6982

贵宾VX城市地图大赛冠军第1届RMTV比赛冠军第1届TG大赛冠军

7
发表于 2010-8-27 12:00:10 | 只看该作者
实际只要重载Point的等于、小于比较符就能直接用Point对象做key值完成了吧

点评

重载这些能够实现二元关系,但如果要用散列结构的话,还需要找到散列码  发表于 2010-8-27 13:12
神隐中,偶尔诈尸
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
8
发表于 2010-8-27 12:02:24 | 只看该作者
本帖最后由 小幽的马甲 于 2010-8-27 12:47 编辑
  1. hash = (@a << 14) + @b
  2. return hash
复制代码
= =这样行么……
-------------------------------------------
忘记有符号了……

  1.     aa = @a >= 0 ? 1 : 0
  2.     bb = @b >= 0 ? 1 : 0
  3.     @a = (aa << 14) | @a.abs
  4.     @b = @b.abs
  5.     hash = (@a << 14) + @b
  6.     hash = - hash if aa ^ bb == 1
  7.     return hash
复制代码
= =

点评

暂时想不出什么方法了,等其他高人解答~  发表于 2010-8-27 15:33
是按照数的位数来位移么……粗略一想,位移量是变量的话,似乎难免碰撞吧?固定量 X 的位移可以保证高 X 位独立于低 X 位,而变量位移则无法保证  发表于 2010-8-27 14:58
也就是返回的hash值可以是Bignum么?那么把那个14改成(Math.log([@a,@b].max)/Math.log(2)).to_i+1行么= =  发表于 2010-8-27 13:39
不错~这个方法很直观,只是建立在顶楼的上限假设上,该假设只是为了方便测试(hash 只接受 Fixnum),实际上有泛用的方法,返回任意大小的散列码  发表于 2010-8-27 13:30

评分

参与人数 1星屑 +240 收起 理由
紫苏 + 240

查看全部评分

From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1185
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

9
发表于 2010-8-27 12:06:41 | 只看该作者
本帖最后由 DeathKing 于 2010-8-27 13:17 编辑
  1. class Point
  2.   def hash
  3.     return "#{@x}.#{@y.to_s.resive}".to_f
  4.   end
  5. end
复制代码
hash只能接受Integer(Fixnum)么{:nm_3:}
正在考虑返回Fixnum的方法。




好吧,仔细看看这道题并不难,我认为应该这样理解。

1、p ∈ Point; x,y∈Fixnum; h∈Hash(Fixnum)
2、求映射函数GET_HASH:p -> h,且是一个1对1的函数

也就是让我们构建一个二元函数,GET_HASH(x,y),返回一个Fixnum,那么就要找到一个类似与MD5一样的算法就行了。

其他思路整理中。

点评

2^15^2 = 2^30,所以说是为了方便测试,因为在 Fixnum 范围内 o.o  发表于 2010-8-27 13:33
0_0  发表于 2010-8-27 12:23
不但有负数的问题,而且如果不翻转字符串的话,y值的1000和1都一样 0_0  发表于 2010-8-27 12:20
死君殿啊,有负数呢= =话说愚者第一个也想到这个了  发表于 2010-8-27 12:18

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv3.寻梦者

宛若

梦石
0
星屑
1568
在线时间
526 小时
注册时间
2007-8-19
帖子
1493

极短24参与开拓者

10
发表于 2010-8-27 12:29:03 | 只看该作者
本帖最后由 逸豫 于 2010-8-27 12:58 编辑

恩……最大15位么……
那就用一个100000000000000进制的数……
恩……第一位位放x,第二位位放y,转成10进制
什么效率什么的不关我事……

晕……原来是2进制15位……果然我做题不读题的优良传统依然保持么- -|||

点评

此方法也需要依靠数据规模的限定- -|||无视无视……  发表于 2010-8-27 18:38
呵呵,有意思,不妨说一下如果是 2 进制怎么办?  发表于 2010-8-27 15:21
[url=http://rpg.blue/thread-219730-1-1.html]http://unhero.sinaapp.com/wi.php[/url]
[color=Red]如你所见这是个死坑,没错这就是打我的脸用的[/color]
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-21 20:07

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表