2010-01-10 46 views
6

我有以下Python函數遞歸找到一套的所有分區:翻譯功能尋找一組所有分區在Python和Ruby

def partitions(set_): 
    if not set_: 
     yield [] 
     return 
    for i in xrange(2**len(set_)/2): 
     parts = [set(), set()] 
     for item in set_: 
      parts[i&1].add(item) 
      i >>= 1 
     for b in partitions(parts[1]): 
      yield [parts[0]]+b 

for p in partitions(["a", "b", "c", "d"]): 
print(p) 

有人可以幫我翻譯成紅寶石嗎?這是我迄今爲止:

def partitions(set) 
    if not set 
    yield [] 
    return 
    end 
    (0...2**set.size/2).each { |i| 
    parts = [Set.new, Set.new] 
    set.each { |item| 
     parts[i&1] << item 
     i >>= 1 
    } 
    partitions(parts[1]).each { |b| 
     yield [parts[0]] << b 
    } 
    } 
end 

p partitions([1, 2, 3, 4].to_set) 

我收到錯誤「LocalJumpError:no block given」。我想這是因爲在Python和Ruby中yield函數的工作方式不同。

+0

你在哪裏找到的Python功能分區的時候離開了。每個?爲了讓事情和學習情境化,我想閱讀您發現它的博客條目或章節。謝謝。 – 2015-04-21 12:36:06

回答

4
#!/usr/bin/ruby1.8 

def partitions(set) 
    yield [] if set.empty? 
    (0 ... 2 ** set.size/2).each do |i| 
    parts = [[], []] 
    set.each do |item| 
     parts[i & 1] << item 
     i >>= 1 
    end 
    partitions(parts[1]) do |b| 
     result = [parts[0]] + b 
     result = result.reject do |e| 
     e.empty? 
     end 
     yield result 
    end 
    end 
end 

partitions([1, 2, 3, 4]) do |e| 
    p e 
end 

# => [[1, 2, 3, 4]] 
# => [[2, 3, 4], [1]] 
# => [[1, 3, 4], [2]] 
# => [[3, 4], [1, 2]] 
# => [[3, 4], [2], [1]] 
# => [[1, 2, 4], [3]] 
# => [[2, 4], [1, 3]] 
# => [[2, 4], [3], [1]] 
# => [[1, 4], [2, 3]] 
# => [[1, 4], [3], [2]] 
# => [[4], [1, 2, 3]] 
# => [[4], [2, 3], [1]] 
# => [[4], [1, 3], [2]] 
# => [[4], [3], [1, 2]] 
# => [[4], [3], [2], [1]] 

有什麼不同:

  • 衛兵調用set.empty?而不是 (隱式)測試set.nil?
  • 調用 分區
  • 使用數組,而不是一套
  • 過濾空套出產生 結果
+0

非常感謝! – tom 2010-01-11 08:34:08

0

您將不得不考慮Ruby的yield,就像調用用戶定義的操作一樣。

def twice 
    yield 
    yield 
end 

twice { puts "Hello" } 

所以,只要你的代碼產生一個值,這個元素的處理函數就會被調用。

partitions([1, 2, 3, 4].to_set) { |result| 
    # process result 
} 

此代碼根本不會生成列表。