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

Project1

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

[讨论] o(1)的算法也许并不是最优化的……脚本语言太神奇了

[复制链接]

Lv5.捕梦者 (版主)

遠航の猫咪

梦石
3
星屑
23186
在线时间
2387 小时
注册时间
2005-10-15
帖子
1166

开拓者

跳转到指定楼层
1
发表于 2018-1-16 14:59:35 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 SailCat 于 2018-1-16 15:12 编辑

ruby的1.81没有Array#sample

正在开发的插件,要大量的运用到sample操作,没办法,自己写一个

第一个版本:
RUBY 代码复制
  1. class Array
  2.   # Implement sample for Ruby 1.9+
  3.   def sample1(n=1)
  4.     return self[rand(size)] if n == 1
  5.     t = clone; n = [[n, size].min, 0].max; a = []
  6.     n.times { a.push(t.slice!(rand(t.size)))}
  7.     a
  8.   end
  9. end

复杂度o(n!)

写出来就觉得slice!太粗暴了,o(n!)就是因为它,想改改

第二个版本:
RUBY 代码复制
  1. class Array
  2.   # Implement sample for Ruby 1.9+
  3.   def sample2(n=1)
  4.     n == 1 ? self[rand(size)] : sort_by{rand(0)}[0...([[n, size].min, 0].max)]
  5.   end
  6. end


这是个o(1)的算法,而且写法最简单,一行搞定
顺便说一下 sort_by{rand(0)}是我从sql的写法中得到的灵感,ruby1.81也没有shuffle,我用这个方法实现了shuffle

一般写成o(1)就觉得很好了,但我觉得哪怕取两个数也要把整个数组重排一遍太小题大作了

第三个版本:
每取一个数,就把最后一个数挪过来
RUBY 代码复制
  1. class Array
  2.   # Implement sample for Ruby 1.9+
  3.   def sample3(n=1)
  4.     return self[rand(size)] if n == 1
  5.     t = clone; n = [[n, size].min, 0].max; a = []
  6.     n.times {|i| d = rand(size-i); a.push(t[d]); t[d] = t[size-1]}
  7.     a
  8.   end
  9. end


差不多了,但还是对push心有余悸,我不知道ruby的解释器是怎么实现变长数组的,但是还是想扔掉push

第四个版本:
取前n个数,随机和后面的数交换
RUBY 代码复制
  1. class Array
  2.   # Implement sample for Ruby 1.9+
  3.   def sample4(n=1)
  4.     return self[rand(size)] if n == 1
  5.     t = clone; n = [[n, size].min, 0].max
  6.     n.times {|i| d = i + rand(size - i); tmp = t[i]; t[i] = t[d]; t[d] = t[i]}
  7.     t[0...n]
  8.   end
  9. end


你们觉得哪个最优化?测试的结果可能和你们想的不一样哦。

测试代码和结果


评分

参与人数 1+1 收起 理由
tjjlb + 1 塞糖

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。

Lv4.逐梦者

梦石
0
星屑
9280
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

2
发表于 2018-1-16 15:01:38 | 只看该作者
這4種裏,1.9用的是哪一種···

点评

1.92用的是算法4,其中对n=0到10的情况做了另外的处理(就是硬算)  发表于 2018-1-16 15:34
http://ruby-doc.org/core-1.9.2/Array.html#method-sample  发表于 2018-1-16 15:14
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
0
星屑
6901
在线时间
7028 小时
注册时间
2013-11-2
帖子
1344

开拓者剧作品鉴家

3
发表于 2018-1-16 15:19:50 | 只看该作者

大佬,你是不是完全无视了sort_by本身的复杂度和运行效率啊?

点评

放假之后的雷霆突然活跃起来~  发表于 2018-1-16 17:23
就sample本身处理的时长和所传入的参数n的关系来说,是o(1)啊……几次测试的时间也是恒定的>_<  发表于 2018-1-16 15:31
本人才疏学浅,还请大佬指点迷津。  发表于 2018-1-16 15:28
我针对的是标题。这哪儿o(1)了啊?  发表于 2018-1-16 15:24
我说了啊,取2个数要把全数组排一遍太麻烦了,语法糖毕竟只是语法糖……所以后面才写了算法3和4  发表于 2018-1-16 15:22
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1342
在线时间
675 小时
注册时间
2009-11-11
帖子
2790
4
发表于 2018-1-16 18:59:05 | 只看该作者
机器码是最快的了,代码运行中全部都翻译成0和1,最底层的最快,对于C来说是这样的,鬼知道rm进行了什么奇怪的处理

嘿。嘿。嘿
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
4598
在线时间
1206 小时
注册时间
2016-4-7
帖子
982

开拓者

5
发表于 2018-1-17 09:05:57 | 只看该作者
最优化的当然是jeff的O(1/n)啦 越多越快

点评

笑死  发表于 2018-1-19 03:59
附庸的附庸不是我的附庸,女儿的女儿还是我的女儿。CK2沉迷ing
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1803
在线时间
133 小时
注册时间
2013-10-6
帖子
193
6
发表于 2018-1-19 04:00:34 | 只看该作者
复杂度不是这么看的...
←你看到一只经常潜水的萌新。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-14 23:27

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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