要看看有什么困难,让我们用一个更简单的例子来试试吧:
string = "ab"
您想要的结果是["ab", "ba"]。让我们看看你得到了什么:
string.size #=> 2
所以我们什么时候不回来
return [string] if string.size < 2
#=> return ["ab"] if "ab".size < 2
被执行。
接下来我们计算:
chr = string.chars.first #=> "a"
请注意,更直接的计算方法如下:
chr = string[0] #=> "a"
或者,更好的是,使用String#chr,
chr = string.chr #=> "a"
后者说明了为什么chr 不是变量名的最佳选择。
下一个
perms = permutation(string[1..-1])
#=> = permutation("b")
我现在将缩进返回值以强调我们第二次调用permutation。 permuation的论据是:
string #=> "b"
现在当我们执行时:
return [string] if string.size < 2
#=> return ["b"] if "b".size < 2
我们返回["b"],所以(回到原来对permutation的调用):
perms = ["b"]
与chr => "a" 一起使用,之前计算过。下一个:
result = []
for perm in perms
for i in (0..perm.size)
result << (perm[0..i] + chr + perm[i..-1])
end
end
由于perms 仅包含单个元素"b",因此两个for 循环简化为:
for i in (0.."b".size)
result << ("b"[0..i] + "a" + "b"[i..-1])
end
这是:
for i in (0..1)
result << ("b"[0..i] + "a" + "b"[i..-1])
end
请注意,"b"[0..0]、"b"[0..1] 和 "b"[0..-1] 都等于 "b"[0],也就是 "b" 和 "b"[1..-1] #=> ''。因此,当i => 0时,我们执行:
result << ("b"[0..0] + "a" + "b"[0..-1])
#=> result << ("b" + "a" + "b")
#=> result << "bab"
当i => 1:
result << ("b"[0..1] + "a" + "b"[1..-1])
#=> result << ("b" + "a" + "")
#=> result << "ba"
所以:
result => ["bab" + "ba"]
这显然不是你想要的。
您需要做的是将双 for 循环更改为:
for perm in perms
result << chr + perm
for i in (1..perm.size-1)
result << (perm[0..i-1] + chr + perm[i..-1])
end
result << perm + chr
end
使用String#insert方法可以写得更简洁:
for perm in perms
for i in (0..perm.size)
result << perm.dup.insert(i,chr)
end
end
你通常会看到这样写:
perms.each_with_object([]) do |perm, result|
(0..perm.size).each { |i| result << perm.dup.insert(i,chr) }
end
请注意,在发送insert 之前,我们必须先.dup 字符串,因为insert 会修改字符串。
这样做,你不需要result = []。也不需要return result,因为parms.each_with_object 返回result,如果没有return 语句,该方法返回最后计算的数量。此外,您不需要临时变量 perms(或 ch,如果需要)。
总而言之,我们有:
def permutation(string)
return [string] if string.size < 2
ch = string[0]
permutation(string[1..-1]).each_with_object([]) do |perm, result|
(0..perm.size).each { |i| result << perm.dup.insert(i,ch) }
end
end
让我们试试吧:
permutation("ab")
#=> ["ab", "ba"]
permutation("abc")
#=> ["abc", "bac", "bca", "acb", "cab", "cba"]
permutation("abcd")
#=> ["abcd", "bacd", "bcad", "bcda", "acbd", "cabd",
# "cbad", "cbda", "acdb", "cadb", "cdab", "cdba",
# "abdc", "badc", "bdac", "bdca", "adbc", "dabc",
# "dbac", "dbca", "adcb", "dacb", "dcab", "dcba"]
Eki,你是图中的哪一个?