置换的递归解决方案

时间:2011-12-25 04:01:01

标签: ruby algorithm data-structures recursion

我有一个如下所示的数据结构:

[
  {:choices=>["Hello", "Hi"]}, 
  " ", 
  {:choices=>["wor", {:choices=>["ld", "d"]}, "there"]}, 
  ", says ", 
  "your ", 
  {:choices=>["friend", "amigo"]}
]

在此结构中,选择节点表示一组可能的值,可以组合。

我需要一个(可能是递归的)Ruby方法,它将输出所有可能输出的数组。即,对于这个例子:

[
  "Hello word, says your friend",
  "Hello world, says your friend",
  "Hello there, says your friend",
  "Hi word, says your friend",
  "Hi world, says your friend",
  "Hi there, says your friend",
  "Hello word, says your amigo",
  "Hello world, says your amigo",
  "Hello there, says your amigo",
  "Hi word, says your amigo",
  "Hi world, says your amigo",
  "Hi there, says your amigo"
]

我希望这是递归的,但我一直在敲打它一小时,我想要另一双眼睛。我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

让原始数据为a,我想您想要的是:

def expand s, x = nil, *a
    case x
    when Hash then x[:choices].each{|x| expand(s, x, *a)}
    when Array then expand(s, *x, *a)
    when String then expand(s+x, *a)
    when nil then @combination << s
    end 
end

@combination = []
expand("", a)
@combination # => result

但是你提供的数据是错误的。它没有给出你想要的东西:

a = [
    {:choices=>["Hello", "Hi"]},
    " ",
    {:choices=>["wor", {:choices=>["ld", "d"]}, "there"]},
    ", says ",
    "your ",
    {:choices=>["friend", "amigo"]}
]

@combination = []
expand("", a)
@combination # =>
["Hello wor, says your friend",
 "Hello wor, says your amigo",
 "Hello ld, says your friend",
 "Hello ld, says your amigo",
 "Hello d, says your friend",
 "Hello d, says your amigo",
 "Hello there, says your friend",
 "Hello there, says your amigo",
 "Hi wor, says your friend",
 "Hi wor, says your amigo",
 "Hi ld, says your friend",
 "Hi ld, says your amigo",
 "Hi d, says your friend",
 "Hi d, says your amigo",
 "Hi there, says your friend",
 "Hi there, says your amigo"]

如果您将其更改为

a = [
    {:choices=>["Hello", "Hi"]},
    " ",
    {:choices=>[[
        "wor",
        {:choices=>["ld", "d"]}
    ], "there"]},
    ", says ",
    "your ",
    {:choices=>["friend", "amigo"]}
 ]

然后你会得到:

@combination = []
expand("", a)
@combination # =>
["Hello world, says your friend",
 "Hello world, says your amigo",
 "Hello word, says your friend",
 "Hello word, says your amigo",
 "Hello there, says your friend",
 "Hello there, says your amigo",
 "Hi world, says your friend",
 "Hi world, says your amigo",
 "Hi word, says your friend",
 "Hi word, says your amigo",
 "Hi there, says your friend",
 "Hi there, says your amigo"]