这是问题
洗牌。现在你已经完成了 新的排序算法,怎么样 相反?写一个shuffle方法 采取数组并完全返回 洗牌版。一如既往,你会 想要测试它,但测试这个 比较棘手:你怎么测试 确定你得到了完美 洗牌?你甚至会说什么? 完美的洗牌会是什么?现在测试 它
这是我的代码答案:
def shuffle arr
x = arr.length
while x != 0
new_arr = []
rand_arr = (rand(x))
x--
new_arr.push rand_arr
arr.pop rand_arr
end
new_arr
end
puts (shuffle ([1,2,3]))
我的错误是什么?为什么这段代码不起作用?
答案 0 :(得分:2)
这是一个更加Rubyish版本:
class Array
def shuffle!
size.downto(1) { |n| push delete_at(rand(n)) }
self
end
end
puts [1,2,3].shuffle!
答案 1 :(得分:2)
这是一种更简洁的写作方式:
def shuffle(arr)
new_arr = []
while (arr.any?) do
new_arr << arr.delete_at(rand(arr.length))
end
new_arr
end
还有一些测试:
5.times do
puts shuffle((1..5).to_a).join(',')
end
>> 4,2,1,3,5
>> 3,2,1,4,5
>> 4,2,5,1,3
>> 5,2,1,4,3
>> 4,3,1,5,2
答案 2 :(得分:1)
您的索引与您的值混淆了。当您执行new_arr.push rand_arr
时,您将所提出的任意随机索引作为new_arr
末尾的值。您打算做的是new_arr.push arr[rand_arr]
,其中arr[rand_arr]
是rand_arr
中索引arr
的值。
答案 3 :(得分:1)
除了轻微的其他错误之外,您似乎无法理解pop和push正在做什么(从数组末尾获取或添加一些项目)。
您可能正在尝试编写类似下面的内容。
def shuffle arr
x = arr.length
new_arr = []
while x != 0
randpos = rand(x)
x = x-1
item = arr[randpos]
new_arr.push item
arr[randpos] = arr[x]
arr.pop
end
new_arr
end
puts (shuffle ([1,2,3]))
答案 4 :(得分:0)
Ruby 1.8.7和1.9.2有一个内置的Array #shuffle方法。
答案 5 :(得分:0)
马克·托马斯答案的变体。由于删除操作性能,他的算法对于大型数组来说可能非常慢。
class Array
def shuffle!
size.downto(1) do |n|
index=rand(n)
# swap elements at index and the end
self[index], self[size-1] = self[size-1],self[index]
end
self
end
end
puts [1,2,3].shuffle!
此算法为O(大小),而Mark的算法为O(大小为^ 2)。在我的计算机上,Mark的答案需要400秒才能在我的机器上洗涤1,000,000个元素,而使用我的方法则为0.5秒。