嵌套对象的所有组合

时间:2019-04-21 19:34:11

标签: javascript algorithm recursion

我有以下字符串

Hello, have a {good {night|day}|wonderful {evening|morning}} and {goodbye|bye}!

我正在尝试生成所有字符串组合。 例如: Hello, have a good day and bye!Hello, have a wonderful evening and goodbye!

规则:{one|two}表示第一次写one,第二次写two。如您所见,这些条件可以嵌套任意次。

我已经将其解析为以下结构

[
 "Hello, have a ",
 {
  "or": [
   [
    "good ",
    {
     "or": [
      "night",
      "day"
     ]
    }
   ],
   [
    "wonderful ",
    {
     "or": [
      "evening",
      "morning"
     ]
    }
   ]
  ]
 },
 " and ",
 {
  "or": [
   "goodbye",
   "bye"
  ]
 },
 "!"
]

现在我不知道如何从该结构生成所有字符串。

1 个答案:

答案 0 :(得分:1)

您可以在解析时直接生成句子,基本上,您只需要经历所有可能性:

function generateSentences(s) {
    const start = s.indexOf('{') + 1
    if (start == 0)
        return [s]
    for (let i = start, braces = 1;; i++)
        if (s[i] == '{')
            braces++
        else if (s[i] == '}')
            if (--braces == 0) {
                const options = generateOptions(s.substring(start, i)),
                      posts = generateSentences(s.substr(i + 1)),
                      pre = s.substring(0, start - 1)
                let sentences = []
                for (const option of options)
                    for (const post of posts)
                        sentences.push(pre + option + post)
                return sentences
            }
}
function generateOptions(options) {
    let braces = 0, start = 0, sentences = []
    for (let i = 0; i < options.length; i++)
        if (options[i] == '{')
            braces++
        else if (options[i] == '}')
            braces--
        else if (options[i] == '|' && braces == 0) {
            sentences = sentences.concat(generateSentences(options.substring(start, i)))
            start = i + 1
        }
    return sentences.concat(generateSentences(options.substring(start, options.length)))
}
console.log(generateSentences('Hello, have a {good {night|day}|wonderful {evening|morning}}!'))
console.log(generateSentences('hello, {|111|{!2!|@2@} 222|33 {@333@|444} 3333}! 555. {666|{777 {888|999}}} end...'))