Project1

标题: 来帮我做个hash的新方法! [打印本页]

作者: end55rpg    时间: 2012-4-21 18:17
标题: 来帮我做个hash的新方法!
本帖最后由 end55rpg 于 2012-4-21 19:58 编辑

就是帮我做个方法,索引为数组的hash才可以用= =!
如下@hash变量.方法名(传入实参1,实参2)
实参1就是个数组实参2是让来当差值的。
定义个新方法,获取hash中的索引最相似的一个。= =
比如,传进[126,256]
哈希是 = {[100,200 => "我"[300,500 => “你”}
这个方法返回的就是“我”,应该要排2次序吧= =

数组:传入的里面都是数,没有其他类。还有哈希索引的数组也一样
差值数组每项的与中的索哈希数组的差,就相当于设定范围吧。。。。           不知道什么意思就不做这个吧,就取数最近的一个吧


对了,帮我做个效率高的。。。。
(处理10亿字节的hash提取出来RGSS无压力就行了= =)


dsu_plus_rewardpost_czw
作者: 吉井明久    时间: 2012-4-21 18:25
本帖最后由 吉井明久 于 2012-4-21 20:35 编辑

不理解差值是什么意思。
没有考虑效率是这样的…
  1. class Hash
  2.   def nearest(j)
  3.     self[self.keys.min_by{  |i| i.length.times.map{ |x| (i[x] - j[x]).abs}.inject{ |a, b| a -= -b}}]
  4.   end
  5. end
复制代码

作者: end55rpg    时间: 2012-4-21 18:48
本帖最后由 end55rpg 于 2012-4-22 14:13 编辑
吉井明久 发表于 2012-4-21 18:25
不理解差值是什么意思。
没有考虑效率是这样的…

不行啊,就算我传入的数组和索引数组一模一样还是返回nil,你试过没有吖= =���@吉井明久
@吉井明久这个是我写的,只做成了判断数组【0。。1】
RUBY 代码复制
  1. class Hash
  2.   def nearest(array)#传入匹配样式
  3.     self.sort{|a,b|a[0][0] <=> array[0]}[0..2].sort{|a,b|a[0][1]<=>array[1]}[0]
  4.   end
  5. end
  6. hash = {[10,2] => "十、二",[5,3] => "五、三",[9,0] => "九,零",[7,2] => "七,二",[6,4] => "六,四"}
  7. p hash.nearest([5,5])#显示:[[7,2] , "七,二"]

先排数组第一个项的序,然后排第2个的序,这样肯定效率超级坑爹。。。。

������
  1. class Hash
  2.   def nearest(j)
  3.     self[self.keys.min_by{  |i| i.length.times.map{ |x| (i[x] - j[x]).abs}.inject{ |a, b| a -= -b}}]
  4.   end
  5. end
  6. hash = {[1000,200] => "十、二",[5,3] => "五、三",[9,0] => "九,零",[7,2] => "七,二",[6,4] => "六,四"}
  7. p hash.nearest([100,200])
  8. #错误消息为:undefined method `min_by' for [[1000, 200], [9, 0], [5, 3], [6, 4], [7, 2]]:Array
复制代码

’’
作者: 吉井明久    时间: 2012-4-21 20:09
本帖最后由 吉井明久 于 2012-4-21 21:20 编辑

100 次从 1000 个里面找。
  1.              user     system      total        real
  2. mine     0.280000   0.000000   0.280000(  0.283317)
  3. end55    4.540000   0.010000   4.550000 (  4.559853)
  4. []       0.000000   0.000000   0.000000 (  0.000129)
复制代码
你看速度已经快得多了。

先为每个计算 key 与 pattern 的差将其绝对值相加然后排序…

你看这里一个mne2, nearest3限制了单位10,
http://ideone.com/9gfrL
速度更快了,但是无效的也会增加因为有限制了。

@end55rpg,如果数据稀疏的话…等等。好像可以,我试试。
作者: end55rpg    时间: 2012-4-21 20:19
本帖最后由 end55rpg 于 2012-4-21 20:37 编辑

@吉井明久
嗯,看到了
还有我有个方案不知可行不:由于数组内是整数,就按照传入样式加减1来来获取,如果获取的是nil继续加减2,这样以传入样式当原点来向左右来算
这个方案可以不,就不用排序,只需要用[]来获取,如果hash内有1000*10000个获取100次,才只需1.29S?(根据测试速度估算的)


刚刚我测试一下,你的排序脚本和我的对比:
1000个数据的hash,获取1000次:
你的   我的
1s      2s
作者: 吉井明久    时间: 2012-4-21 21:32
  1.                          user     system      total        real
  2. nearest        1000 2.700000   0.000000   2.700000 (  2.712052)
  3. nearest_s 3    1000 3.930000   0.000000   3.930000 (  3.944038)
  4. nearest_s 2    1000 1.800000   0.000000   1.800000 (  1.805068)
  5. nearest_s 1     201 1.750000   0.000000   1.750000 (  1.768153)
  6. tortoise 2     1000 1.770000   0.000000   1.770000 (  1.771551)
  7. tortoise 1      349 0.590000   0.010000   0.600000 (  0.588352)
  8. []              1000 0.000000   0.000000   0.000000 (  0.001369)
复制代码

1000次1000个。
因为n的缩小所以匹配数并非永远1000。

  1. class Hash
  2.   def tortoise(j, n=100)
  3.     x = j.dup
  4.     c = proc { return self[x] if self[x] }
  5.     l = 1
  6.     n.times {
  7.       l.times{x[0] -= 1; c.()}
  8.       l.times{x[1] -= 1; c.()}
  9.       (l - -1).times{x[0] -= -1; c.()}
  10.       (l - -1).times{x[1] -= -1; c.()}
  11.       l -= -2
  12.     }
  13.     nil
  14.   end
  15.   def nearest(j)
  16.     self[self.keys.sort_by{  |i| Array.new(i.length){ |x| (i[x] - j[x]).abs}.inject{ |a, b| a -= -b}}[0]]
  17.   end
  18.   def nearest_s(j, n=100)
  19.     self[self.keys.select{|i|Array.new(i.length){ |x| (i[x] - j[x]).abs}.inject{ |a, b| a -= -b} <= n}.sort_by{  |i| Array.new(i.length){ |x| (i[x] - j[x]).abs}.inject{ |a, b| a -= -b}}[0]]
  20.   end
  21. end
  22. require 'benchmark'
  23. a={}
  24. 1000.times{a[b=[rand(1000),rand(1000)]]=b}
  25. n = 1000
  26. z=Array.new(n){[rand(1000),rand(1000)]}
  27. Benchmark.bm(15) do |x|
  28. x.report("nearest") { puts z.map{ |i| a.nearest i}.compact.length }
  29. x.report("nearest_s 3") { puts z.map{ |i| a.nearest_s i,1000}.compact.length }
  30. x.report("nearest_s 2") { puts z.map{ |i| a.nearest_s i,100}.compact.length }
  31. x.report("nearest_s 1") { puts z.map{ |i| a.nearest_s i,10}.compact.length }
  32. x.report("tortoise 2") { puts z.map{ |i| a.tortoise i, 100}.compact.length }
  33. x.report("tortoise 1") { puts z.map{ |i| a.tortoise i, 10}.compact.length }
  34. x.report("[]") { z.each{ |i| a[i]} }
  35. end
复制代码

作者: end55rpg    时间: 2012-4-22 22:39
吉井明久 发表于 2012-4-21 21:32
1000次1000个。
因为n的缩小所以匹配数并非永远1000。

我花了N分钟来读你的代码,好诡异的风格啊,比如a -= -b难道不能些得容易理解点= =,毕竟抽象思考很困难。。。还有你写的那些东东,好像我在RM中很少看到啊,不知道VA有没,比如:Array.new(n){var}
我一般写Array.new(n,var)汗。。。。。。读起来真累啊,还有帮我解释下:
map,inject,dup,proc是干嘛的,怎么用的吧。。。。。(这些东东没看过啊= =)




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1