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

Project1

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

[已经过期] 请教关于Hash值的问题

[复制链接]

Lv1.梦旅人

梦石
0
星屑
167
在线时间
434 小时
注册时间
2009-1-1
帖子
643
跳转到指定楼层
1
发表于 2010-12-10 01:13:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
例如
a = {"阿尔西斯"=>2004, "艾力克斯"=>2000, "杰克"=>2003, "拉尔夫"=>2007}
我想获取以字符串的形式返回里面第二大的值及它所对应的主键名

这里要返回的是
"2004"
"阿尔西斯"
最近在研究XAS

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
2
发表于 2010-12-10 02:15:09 | 只看该作者
  1. a = {"阿尔西斯"=>2004, "艾力克斯"=>2000, "杰克"=>2003, "拉尔夫"=>2007}

  2. lrgt = [ nil, -1.0 / 0 ]
  3. sec_lrgt = [ nil, nil ]

  4. a.each do |k, v|
  5.         if v > lrgt[1]
  6.                 sec_lrgt.replace(lrgt)
  7.                 lrgt = k, v
  8.         end
  9. end

  10. p sec_lrgt
复制代码
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

3
发表于 2010-12-10 03:27:04 | 只看该作者
max2_value = a.values.sort[-2]
max2_value_str = max2_value.to_s
max2_value_index = a.index(max2_value).to_s
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
4
发表于 2010-12-10 04:09:37 | 只看该作者
本帖最后由 苏小脉 于 2010-12-10 04:10 编辑

回复 六祈 的帖子

排序的主要问题是有额外的不容忽视的开销:
如果 m = 散列表桶的数量,n = 实际的元素(键值对)个数,那么二楼的方法需要 O(m) 时间,而三楼的方法却是 O(m)+O(n*log(n)),分别是 Hash#value 和 Array#sort 需要的时间,无论 m 是否大于 n,O(m)+O(n*log(n)) 都大于 O(m):victory:
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

5
发表于 2010-12-10 11:11:47 | 只看该作者
回复 苏小脉 的帖子

如今论坛点评会吃进回复,于是只有回复了。
紫苏大人的方法诚然效率更高,不过愚者以为如果这个哈希表并不大的话,似乎应该不用在意。
另外求教下紫苏大人,愚者之前曾试过对一个上百万元素的数组使用sort[-1]取最大值和max取最大值,结果发现sort[-1]耗时极短,而max则比之至少慢了上百倍


六祈于2010-12-10 11:22补充以下内容:
点评他人会吃进自己的回复。。可怕

点评

不知道搞什么RUBY的maxmin确实效率很低OJZ  发表于 2010-12-10 11:34
先回复再点评才会吃。  发表于 2010-12-10 11:22
应该只有点评自己回“吃进回复”吧 o.o  发表于 2010-12-10 11:19
直接点评没事啊=.= 论坛又给挂马了。。  发表于 2010-12-10 11:15
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
6
发表于 2010-12-10 11:46:33 | 只看该作者
回复 六祈 的帖子

理论上不应该出现这么诡异的现象呀,虽说 Ruby 的 Array#sort 底层是一个高度优化的 quicksort 实现,但无论如何也是 O(n*log(n)),不可能比 max 的 O(n) 快,除非 max 带的块里面有什么糟糕物。能否提供再现问题的代码?
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

7
发表于 2010-12-10 11:57:54 | 只看该作者
本帖最后由 六祈 于 2010-12-10 12:00 编辑

回复 苏小脉 的帖子

  1. def time_1000
  2. start=Time.now
  3. 1000.times do
  4. yield
  5. end
  6. stop = Time.now
  7. puts stop - start
  8. end
  9. a=*1..10000

复制代码
好像没有上百倍那么夸张,不过目前是15倍左右的差距吧。诡异
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
8
发表于 2010-12-10 21:25:58 | 只看该作者
回复 六祈 的帖子

简单分析了一下源代码,大概是这样:

quicksort 在不同的场合下性能不同,它的核心是分治法,分治用的枢轴(pivot)选择是决定时间效率的关键。最好的情况下,是每一次分治都能选到当前分区的中数作为枢轴,然后再分,这需要 O(n*log(n))。你给的例子中的数组,元素按严格的升序排列,这在底层的实现中是一个优化的机会,它能选到更好的枢轴。最坏的情况下,是选到当前分区的最小或最大的数,而如果每次分治都出现这种情况,quicksort 则需要 O(n^2) 的时间。所以如果用下面这样的乱序数组,Array#sort 耗时就比较高了:
  1. CASES = 10000

  2. arr = [ ]
  3. CASES.times do
  4.         arr << rand(CASES)
  5. end
复制代码
至于 max,它确实很慢,因为它底层还是通过 rb_function_call 去调用了 Ruby 层面的 each 方法进行迭代,然后在里面又调用 Ruby 层面的比较方法(< 和 >),还不提中间的一堆其它杂项处理又封了不少层,其中就包括迭代器的处理,这些都是职业的效率杀手。Array#sort 则不同,一旦调用就全权交给 C 进行高效的排序,不会再回来调用 Ruby。想来也是出于设计上的限制,因为 max (还包括像另一帖讨论过的 inject 的不少函数)是给 Enumerable 模块定义的,它直接抽象为调用 Mixin 这个模块的类的相应函数(each、<=>、<、> 等)来实现枚举,所以和实现了 Enumerable 这个接口的类的细节无关。

理论上来讲,Enumerable#max 仍然是 O(n),Array#sort 仍然是 O(n log n),但真实世界中变数很多,往往和理论有所差异。话说回来,Big-O 毕竟只是一种初级的分析算法的标记法,高级的我也还没接触过,并不能真当成红宝书来用。就好比我有固定 n = 一百万的数据量,由于 n 是常量,所以理论上对数据的运算应该是 O(1) 内完成,但实际上数据量已经到了 O(n) 的级别。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
167
在线时间
434 小时
注册时间
2009-1-1
帖子
643
9
 楼主| 发表于 2010-12-11 22:54:15 | 只看该作者
两个方法都能实现,最后使用的是六祈的比较简单
两位打了那么多字也挺辛苦,就都认可一下吧

点评

认可是认可和主题的问题直接有关的答案,打字是回答者自愿的,无须额外考虑。  发表于 2010-12-12 00:51
最近在研究XAS
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-16 00:51

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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