2012-08-05 203 views
1

我有以下代碼來列出給定字符串的所有可能的排列。但由於我的拙劣列表(ruby數組)操作和功能編程方面的知識有限,我不得不使用flatten來獲得結果數組。這幾乎是一個黑客。我如何重構代碼並避免使用(濫用)變平?如何微調地圖功能,避免使用拼合

class String 
    def remove_char_at(i) 
    if i==0 
     self[1..-1] 
    else 
     self[0..i-1] + self[i+1..-1] 
    end 
    end 
end 

def permute(str,prefix="") 

    if str.size==0 
    prefix 
    else 
    str.chars.each_with_index.map do |s,i| 
     permute(str.remove_char_at(i),prefix+s) 
    end.flatten 
    end 

end 

回答

2

您可以找到有關函數式編程intresting東西在SICP

def permute2(str,prefix="") 

    if str.size==0 
    [prefix] #revise for concatenate with memo 
    else 
    str.chars.each_with_index.inject([]) do |memo, ary| 
     s = ary[0] 
     i = ary[1] 
     memo += permute2(str.remove_char_at(i),prefix+s) #memoize 
    end 
    end 

end 
+0

in'block in permute2':無法將String轉換爲Array(TypeError) – lkahtz 2012-08-06 21:44:47

+0

我將返回值調整爲數組。現在它正在工作。 – lkahtz 2012-08-06 21:56:30

+0

雖然我有點找到我的原始版本沒有累加器更容易理解... – lkahtz 2012-08-06 21:57:06

2

Ruby已經爲你做了很多艱苦的工作。爲了讓所有的排列爲一個字符串,MyString的,請執行下列操作:

myString.split('').permutation.map(&:join).uniq 

此拆分字符串組件集成到一個數組;獲取數組的所有排列;將這些加入字符串;消除重複。

+0

由於如下進行重構,這是有幫助的。但我更關心一些對我的ruby代碼的重構建議,以便我可以獲得一些線索來磨練我對函數式編程的理解。 – lkahtz 2012-08-05 23:55:38

1

第一章我專門回答我如何重構代碼,避免使用(濫用)拉平?部分:

而不是map + flatten,你可以使用它在1.9.2介紹flat_map

2
class String 
    def remove_char_at(i) 
    if i==0 
     self[1..-1] 
    else 
     self[0..i-1] + self[i+1..-1] 
    end 
    end 
end 

可以通過使用...代替..

class String 
    def remove_char_at(i) 
    self[0...i] + self[i+1..-1] 
    end 
end 
+0

Awwwwsome!愛它! – lkahtz 2012-08-07 00:45:40