2012-01-26 38 views
5

Tôi đã câu hỏi quen thuộc này trông giống như hoán vị/kết hợp của thế giới toán học.Làm thế nào để kết hợp/hoán vị trong ruby?

Làm thế nào tôi có thể đạt được sau qua ruby?

badges = "1-2-3" 

badge_cascade = [] 
badges.split("-").each do |b| 
    badge_cascade << b 
end 

Gives: => ["1", "2", "3"] 

But I want it to be is: 

=> ["1", "2", "3", 
    "1-2", "2-3", "3-1", "2-1", "3-2", "1-3", 
    "1-2-3", "2-3-1", "3-1-2"] 
+1

các giá trị dự kiến ​​cho hoán vị của 3 yếu tố trông lạ, chỉ có 3 yếu tố? Tôi đếm 6. – tokland

Trả lời

7

cách tiếp cận chức năng:

bs = "1-2-3".split("-") 
strings = 1.upto(bs.size).flat_map do |n| 
    bs.permutation(n).map { |vs| vs.join("-") } 
end 
#=> ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"] 
5

Bạn định nghĩa để sử dụng Array#permutation phương pháp để có được tất cả các hoán vị:

arr = "1-2-3".split '-' # => ["1", "2", "3"] 
res = (1..arr.length).reduce([]) { |res, length| 
    res += arr.permutation(length).to_a 
}.map {|arr| arr.join('-')} 

puts res.inspect 
# => ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"] 

Hãy để tôi giải thích mã:

  1. Bạn chia chuỗi thành mảng đi qua tách '-'-String#split phương pháp

  2. Bạn cần tất cả hoán vị có độ dài 1, 2, 3. Phạm vi 1..arr.length thể hiện tất cả các độ dài này.

  3. Bạn thu thập một mảng của tất cả các hoán vị sử dụng Enumerable#reduce. Bạn sẽ nhận được hàng loạt các mảng ở đây:

    [["1"], ["2"], ["3"], ["1", "2"], ["1", "3"], ["2", "1"], ["2", "3"], ["3", "1"], ["3", "2"], ["1", "2", "3"], ["1", "3", "2"], ["2", "1", "3"], ["2", "3", "1"], ["3", "1", "2"], ["3", "2", "1"]] 
    
  4. Bạn chuyển đổi tất cả các subarrays của mảng này thành chuỗi sử dụng Array#join với '-' tách của bạn bên trong Enumerable#map

+0

lưu ý rằng bạn đang bắt chước trừu tượng 'flat_map' hiện với '+' reduce' concat'. – tokland

1

Array#permutation(n) sẽ cung cấp cho bạn tất cả các hoán vị của chiều dài n như một mảng của mảng, do đó bạn có thể gọi đây là với mỗi chiều dài giữa 1 và số chữ số trong phù hiệu. Bước cuối cùng là ánh xạ tất cả các chuỗi này vào các chuỗi được phân tách bằng -.

badges = "1-2-3" 

badges_split = badges.split('-') 

permutations = [] 

(1..badges_split.size).each do |n| 
    permutations += badges_split.permutation(n).to_a 
end 

result = permutations.map { |permutation| permutation.join('-') } 

Cập nhật:Tôi nghĩ rằng sử dụng reduce Alex là một cách tiếp cận nhã hơn nhưng tôi sẽ để lại câu trả lời này vào đây để bây giờ trong trường hợp nó rất hữu ích.

Các vấn đề liên quan