2009-11-16 79 views
0

將以下Python方法正確轉換爲Ruby會是什麼?將python方法轉換爲ruby

def uniqueCombinations(self, items, n): 
    """ 
    items: list of elements 
    n: number in a group 
    """ 
    if n == 0: 
     yield [] 
    else: 
     for i in range(len(items)-n+1): 
      for cc in uniqueCombinations(items[i+1:],n-1): 
       yield [items[i]]+cc 

我想要做的就是調用

uniqueCombinations(['01', '02', '03'], 2) 

,並得到

[['01', '02'], ['01', '03'], ['02', '03']] 

這是我到目前爲止所。

def uniq_c(items, n) 
    if n == 0 
    yield [] 
    else 
    puts items.inspect 
    range_max = items.length-n+1 
    for i in (0...range_max) 
     u = uniq_c(items[(i+1)..-1], n-1) { |x| x } 
     u.each do |cc| 
     yield [items[i]] + cc 
     end 
    end 
    end 
end 

,但我得到這個:

in `+': can't convert Fixnum into Array (TypeError) 
+1

python版本可以這樣寫:'return itertools.combinations (items,n)' – nosklo 2009-11-16 10:34:27

回答

0

首先,最好將它作爲Array類的一種方法。

其次,您可以通過將[items[i]] + cc更改爲[items[i]] + [cc]來修復您的錯誤。

第三,我有一個不同的實現,我躺在旁邊,看看你的想法。它創建一個由索引表示的排列數組,然後將每個索引映射到其值。

class Array 
    def combinations(n) 
    perms = [] 
    a = (0...n).to_a 
    while perms.push a.dup 
     break if a.increment!(a.length - 1, self.length-1).nil? 
    end 
    perms.map {|p| p.map {|i| self[i]} } 
    end 
    def increment!(i, max) 
    self[i] += 1 
    while self[i] > max 
     return nil if i <= 0 
     return nil if self.increment!(i - 1, max).nil? 
     self[i] = self[i - 1] + 1 
    end 
    self.dup 
    end 
end 

[1,2,3].combinations 3 # => [[1, 2, 3]] 
[1,2,3].combinations 2 # => [[1, 2], [1, 3], [2, 3]] 
[1,2,3].combinations 1 # => [[1], [2], [3]] 
[:foo,:bar,:baz,:quux,:wibble].combinations 3 
# => [[:foo, :bar, :baz], 
#  [:foo, :bar, :quux], 
#  [:foo, :bar, :wibble], 
#  [:foo, :baz, :quux], 
#  [:foo, :baz, :wibble], 
#  [:foo, :quux, :wibble], 
#  [:bar, :baz, :quux], 
#  [:bar, :baz, :wibble], 
#  [:bar, :quux, :wibble], 
#  [:baz, :quux, :wibble]] 
+0

你的方法就像一個魅力。謝謝。 – 2009-11-16 09:33:29

+0

很高興聽到它!看起來它可能比你的效率低​​,但更容易理解。或者,也許我只是睡眠不足。無論如何,我認爲在Ruby中嘗試使用'yield'是行不通的。 – jtbandes 2009-11-16 09:47:23

2
yield [items[i]] + cc 

您正在試圖串聯的數組([項目[I])和一個Fixnum(CC)。您可以將兩者都轉換爲數組,或使用< <方法將cc推入[items [i]]。

yield [items[i]] << cc 
+0

呃,你輸入的比我快。投票表決。 – 2009-11-16 09:16:24

+0

謝謝。我試過'<<',但函數的最終結果給我的範圍(0..2)。這讓我感到困惑。 – 2009-11-16 09:35:33

2

從紅寶石1.8.7起,類Array提供返回組合的方法:

IRB> [ '01', '02', '03']組合(2).to_a => [[「01」,「02」],[「01」,「03」],[「02」,「03」]]

+0

非常感謝您的意見。 – 2009-11-16 17:16:18