2012-01-04 211 views
1

好吧,我已經在互聯網上搜索答案,也在我的紅寶石程序員搜索了幾個小時,但我無法整理出來。我正在編寫一個腳本,用於根據數組中的元素進行各種組合。紅寶石組合與陣列元素

ar = ["a","b","c","d"] 

在這一點上,我能夠讓這些組合:

["a"],["a","b"],["a","b","c"],["a","b","c","d"],["b"],["b","c"],["b","c","d"],["c"],["c","d"],["d"] 

這是確定的,但我找不到搜索這些組合,例如["a","c"] or ["a","c","d"] or ["a","d"]等方式...

現在我的代碼如下所示:

def combinaties(array) 
    combinaties = [] 
    i=0 
    while i <= array.length-1 
    combinaties << array[i] 
    unless i == array.length-1 
     array[(i+1)..(array.length-1)].each{|volgend_element| 
     combinaties<<(combinaties.last.dup<<volgend_element) 
     } 
    end 
    i+=1 
    end 
end 
+0

你的問題是什麼......? – sethvargo 2012-01-04 22:02:31

+0

你在尋找排列?你可以用數組索引來嘗試。 – three 2012-01-04 22:06:40

+1

@three類數組有一個[置換方法](http://ruby-doc.org/core-1.9.3/Array.html#method-i-permutation)。 – steenslag 2012-01-04 22:32:15

回答

4

有一個簡單的對應於100這種組合與[1 ..(2^m-1)](m是數組長度)中的數字之間的相關(雙射)。

考慮這樣一個數字n。它的二進制表示有m位(包括前導零)。數字1的位置是相應組合中元素的索引。

的代碼將是:

def combinations(array) 
    m = array.length 
    (1...2**m).map do | n | 
    (0...m).select { | i | n[i] == 1 }.map { | i | array[i] } 
    end 
end 
+1

您可以在Ruby中使用按位索引到整數中,以確定某位是否爲1,從而導致更簡單的代碼:http://stackoverflow.com/a/8535241/220147 – 2012-01-05 13:54:10

+0

@MichaelKohl:像這樣? – 2012-01-05 14:05:20

+0

這太棒了!它訣竅!謝謝! – KenGey 2012-01-05 14:33:45

9

Functional方法(需要紅寶石> = 1.9)來創建一個陣列的powerset(除了你似乎並不需要在空元素):

xs = ["a", "b", "c", "d"] 
yss = 1.upto(xs.size).flat_map do |n| 
    xs.combination(n).to_a 
end 

#[ 
# ["a"], ["b"], ["c"], ["d"], 
# ["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"], 
# ["a", "b", "c"], ["a", "b", "d"], ["a", "c", "d"], ["b", "c", "d"], 
# ["a", "b", "c", "d"], 
#] 
+0

這看起來像我需要的!唯一的問題是我堅持使用Ruby 1.8.6 ...這是針對我正在開發的Google SketchUp插件,因此升級Ruby不是一種選擇。無論如何感謝您的迴應!問候 – KenGey 2012-01-05 14:28:02

+0

user1130886:這不是問題,使用https://github.com/marcandre/backports – tokland 2012-01-05 14:46:23

2

或者在紅寶石1.9

%w(a b c d e).combination(3).to_a 

會給你所有的大小爲3的組合。

+0

同樣的問題在這裏,我與Ruby 1.8.6卡住...感謝您的迴應! – KenGey 2012-01-05 14:28:40