一个也使用repeated_permutation 的单线器(我刚从你那里学到的 :-):
s = 'abcd'
[' ', ''].repeated_permutation(s.size - 1).map { |j| s.chars.zip(j).join }
=> ["a b c d", "a b cd", "a bc d", "a bcd", "ab c d", "ab cd", "abc d", "abcd"]
-
repeated_permutation 产生关节,例如 [" ", "", " "]。
-
zip 将它们与字母配对,例如 [["a", " "], ["b", ""], ["c", " "], ["d", nil]]。
-
join 将所有部分转换为字符串并将它们连接起来,例如 "a bc d"。
(注意nil 变成了空字符串,join works recursively,有效地压平了整个结构)。
在我不知道repeated_permutation之前想出的以前的解决方案:
[s[0]].product(*s[1..-1].chars.flat_map { |c| [[' ', ''], [c]] }).map(&:join)
=> ["a b c d", "a b cd", "a bc d", "a bcd", "ab c d", "ab cd", "abc d", "abcd"]
s[1..-1].chars.reduce([s[0]]) { |m, c| m.product([' ', ''], [c]) }.map(&:join)
=> ["a b c d", "a b cd", "a bc d", "a bcd", "ab c d", "ab cd", "abc d", "abcd"]
[''].product(*([[' ', '']] * s.size.pred)).map { |j| s.gsub('') { j.shift } }
=> ["a b c d", "a b cd", "a bc d", "a bcd", "ab c d", "ab cd", "abc d", "abcd"]
(0...2**s.size).step(2).map { |i| s.gsub(/(?!^)/) { ' ' * (1 & i /= 2) } }
=> ["abcd", "a bcd", "ab cd", "a b cd", "abc d", "a bc d", "ab c d", "a b c d"]
它们的基本思想是这样的(为了清楚起见,使用硬编码的字符串):
['a'].product([' ', ''], ['b'], [' ', ''], ['c'], [' ', ''], ['d']).map(&:join)
=> ["a b c d", "a b cd", "a bc d", "a bcd", "ab c d", "ab cd", "abc d", "abcd"]