Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 大集合的唯一置换_Ruby_Algorithm - Fatal编程技术网

Ruby 大集合的唯一置换

Ruby 大集合的唯一置换,ruby,algorithm,Ruby,Algorithm,我试图找到一种方法,为y长度的x值生成唯一的排列。我希望能够做到的是: [0,1].unique_permutations(15) # => [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], # ... massive snip

我试图找到一种方法,为y长度的x值生成唯一的排列。我希望能够做到的是:

[0,1].unique_permutations(15)
# => [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
#     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
#     ... massive snip
#     [1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1],
#     [1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1],
#     ... massive snip
#     [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
#     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
说清楚,我知道这是可能的:

[0, 0, 0, 1, 1, 1].permutation.count
# => 720
[0, 0, 0, 1, 1, 1].permutation.to_a.uniq.count
# => 20
但这与我想要的不太一样,对于长列表,性能变得不切实际:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].permutation.count
# => 479001600 (after a long wait...)
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].permutation.to_a.uniq.count
# => 1 (didn't actually run this - answer is obvious)
我能找到的最接近的东西是,但遗憾的是,我不懂python,也不知道如何将其移植到Ruby


我肯定还有其他算法可以解决这类问题,但我真的很想把它保存在Ruby中。

这里有一个想法-对于
[0,1]
集,您可以从二进制中的0开始计数,只需插入前导零,直到得到长度为15的字符串

n = 15
max = ('1' * n).to_i(2)

(0..max).map do |i|
  i.to_s(2).rjust(n).gsub(" ","0")
end
这个结果几乎可以立即返回置换字符串;将它们转换为整数数组(添加
.split(“”).map(&:to_i)
到块)需要一到两秒钟的时间

这不是一个包罗万象的解决方案(它假设源数组的每个元素至少出现
n次
),但它适用于您的示例。它也应该可以翻译成其他的数字基(我想你可以在Ruby中转换到36基)


编辑:好吧,其他基数可能由于其大小而无法正常工作。但是他们应该让你知道你到底在寻找多少独特的排列;e、 g.长度为15=14348906的3个元素,4个元素为1073741823(也许更熟悉数学的人可以证实这一点)。

递归解决方案可能是这样的(伪代码,因为我的Ruby不是很好):


然后可以用
unique_置换(15,[0,1])
来调用它。您要查找的是一个集本身的
n
-三元笛卡尔积(在您的示例中,
n=15
over set
[0,1]
),这与您在后面的问题中引用的
置换
列表不同

此列表的大小随
n
呈指数增长。除了微小的
n
之外,实际上实现它是不切实际的。你可以用发电机代替(请原谅我生锈的红宝石):

类数组
def笛卡尔_功率(n)
当前=[0]*n
last=[size-1]*n
环道
产生current.reverse.collect{| i | self[i]}
如果当前==最后一个,则中断
(0…n)。每个do |索引|
当前[索引]+=1
当前[索引]%=大小
如果当前[索引]>0,则中断
结束
结束
结束
结束
然后:

[0,1]笛卡尔幂(3){| l | put l.inspect} [0, 0, 0] [0, 0, 1] [0, 1, 0] [0, 1, 1] [1, 0, 0] [1, 0, 1] [1, 1, 0] [1, 1, 1] =>零 >>%w{abc}.笛卡尔幂(2){l}放l.inspect} [“a”,“a”] [“a”、“b”] [“a”、“c”] [“b”、“a”] [“b”,“b”] [“b”、“c”] [“c”、“a”] [“c”、“b”] [“c”,“c”] =>零
适用于仍在这一问题上绊倒的任何人。自从ruby 1.9.2以来,它也做了同样的事情

1.9.2-p320 :056 > 

puts %w(a b c).repeated_permutation(2).map(&:inspect)
["a", "a"]
["a", "b"]
["a", "c"]
["b", "a"]
["b", "b"]
["b", "c"]
["c", "a"]
["c", "b"]
["c", "c"]
 => nil 
1.9.2-p320 :057 > 

{0,1}
的元素只有两种排列:
01
10
。我不确定您在计算什么。@请查看我希望实现的输出的第一个代码块。如果我的预期输出有更准确的术语,我很高兴能更正我的术语。
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]
是否也在您想要的集合中?是否有任何长度为15的
1
0
列表在其中?@phs是的。15项数组中所有可能显示的0和1。这只是一个简单的基数计算问题。这太棒了。谢谢你的专业术语。现在我可以去读笛卡尔积了。这是一个非常好的,非常聪明的答案。谢谢我希望我能接受两个答案,但是@phs在我的问题中涵盖了更一般的情况(y长度的x值)。
1.9.2-p320 :056 > 

puts %w(a b c).repeated_permutation(2).map(&:inspect)
["a", "a"]
["a", "b"]
["a", "c"]
["b", "a"]
["b", "b"]
["b", "c"]
["c", "a"]
["c", "b"]
["c", "c"]
 => nil 
1.9.2-p320 :057 >