因此,我正在为App Academy的训练营进行额外的准备工作,其中一个示例问题是创建一个方法,swingers,它接受一对夫妇的参数并返回一对类似的数组混淆了。
论证的格式如下:([[男,女],[男,女] ..])
我的问题是,大多数时候我执行代码,我收到正确的输出。 但是,有时代码不会执行并陷入循环(我假设)
我确定我没有编写最好的代码,也许我可以改变一些来阻止这个问题。
这是我的代码:
def swingers(couples)
new_couples = []
target_size = couples.size
i = 0
males = couples.each_with_object([]) {|(male,female),arr| arr << male}
females = couples.each_with_object([]) {|(male,female),arr| arr << female}
until new_couples.size == target_size
while true
current_male = males[rand(0..males.size-1)]
current_female = females[rand(0..females.size-1)]
if !couples.include?([current_male,current_female])
break
end
end
males.delete(current_male)
females.delete(current_female)
new_couples[i] = [current_male, current_female]
i += 1
end
new_couples
end
p swingers([
["Clyde", "Bonnie"],
["Paris", "Helen"],
["Romeo", "Juliet"]
])
当我按下ctrl + c(我正在从Windows运行命令行)时,我收到的错误说明:
swingers.rb:14:in
include?': Interrupt from swingers.rb:14:in
swingers' 来自swingers.rb:32:在''
感谢任何帮助,谢谢!
答案 0 :(得分:1)
由于这个测试,你永远结束循环:
if !couples.include?([current_male,current_female])
break
end
最后两对夫妇可能会与原始合作伙伴配对,在这种情况下永远无法联系到break
。
例如,根据您的输入
["Clyde", "Bonnie"],
["Paris", "Helen"],
["Romeo", "Juliet"]
如果你的第一对是克莱德和海伦,而你的第二对是巴黎和邦妮,那只剩下罗密欧与朱丽叶的搭档。你的循环将测试你原来的['Romeo', 'Juliet']
数组中是否存在couples
,他们会这样做,所以它会尝试生成一个新的配对,但是只剩下一个男性和一个女性,所以它永远不会逃避你的while true
。
更适合http://codereview.stackexchange.com
的一些注释不要这样做:
males = couples.each_with_object([]) {|(male,female),arr| arr << male}
这样做:
males = couples.map(&:first)
不要这样做:
current_male = males[rand(0..males.size-1)]
这样做:
current_male = males.sample
略微更天真(但更短且保证完成,假设至少有两对作为输入)方法。这会生成一组完整的新配对,然后会测试原始配对中是否存在任何新配对。
def swingers(pairs)
while true
new_pairs = pairs.map(&:first).zip(pairs.map(&:last).shuffle)
return new_pairs unless new_pairs.any? { |pair| pairs.include? pair }
end
end
答案 1 :(得分:0)
偶尔最后一对最终会与原始合作伙伴结束,因此循环无休止地循环。
某些方法可能会简化您的代码。看看Array#transpose。此外,您可能需要重新考虑您的算法:loop until it fits
容易出现此类错误,而您无法预测它将花费多长时间。
假设您将女性数组旋转一个随机数量的位置(Array#rotate)并压缩两个列表以激发新的配对(Array#zip)。