我目前正在开展一个项目,通过使用无上下文语法规则,我将生成随机句子。现在,我正在创建一个将接收哈希的函数,并遍历它选择正确的产品来创建一个句子并将其作为字符串返回。
例如,给定以下格式的哈希:
{
"<start>"=>[["The", "<object>", "<verb>", "tonight."]],
"<object>"=>[["waves"], ["big", "yellow", "flowers"], ["slugs"]],
"<verb>"=>[["sigh", "<adverb>"], ["portend", "like", "<object>"], ["die", "<adverb>"]],
"<adverb>"=>[["warily"], ["grumpily"]]
}
我应该能够生成一个随机的句子,例如:&#34;波浪在今晚惨死了#34;。
以下是生成此句子的整个过程:
<start>
标签开始生成并继续填写所需的作品。 <start>
并添加&#34;&#34;&#34;然后遇到了#34; <object>
&#34;所以它进入<object>
键并从那里抓取一个随机值,例如["waves"]
。 <verb>
&#34;所以它进入<verb>
键并从那里抓取一个随机值,例如["die", "<adverb>"]
。 <adverb>
&#34;它必须进入<adverb>
键并选择一个随机值,例如[&#34; grumpily&#34;]。 <start>
的末尾,因此它现在可以输出句子。如何编写随机生成句子的方法?
答案 0 :(得分:4)
有趣的运动!
定义String#has_placeholder后?检查&lt;之间的单词和&gt;
只要有占位符,算法就会选择一个起始句并迭代它。如果找到占位符,则将其替换为随机选择的子句。 没有采取任何措施来检查错误。某些占位符可能未定义,或者可能存在无限循环。
它返回一个字符串,它也可以返回一个具有不同深度数组的树。
class String
def has_placeholder?
self=~/<\w+>/
end
end
grammar = {
"<start>"=>[["The", "<object>", "<verb>", "tonight."]],
"<object>"=>[["waves"], ["big", "yellow", "flowers"], ["slugs"]],
"<verb>"=>[["sigh", "<adverb>"], ["portend", "like", "<object>"], ["die", "<adverb>"]],
"<adverb>"=>[["warily"], ["grumpily"]]
}
sentence = grammar["<start>"].sample.join(' ')
while sentence.has_placeholder? do
puts sentence
sentence.sub!(/(<\w+>)/){grammar[$1].sample.join(' ')}
end
puts sentence
输出:
The <object> <verb> tonight.
The slugs <verb> tonight.
The slugs portend like <object> tonight.
The slugs portend like slugs tonight.
或
The <object> <verb> tonight.
The big yellow flowers <verb> tonight.
The big yellow flowers portend like <object> tonight.
The big yellow flowers portend like slugs tonight.
编辑:
您想要的方法如下所示:
def expand(grammar, nonterm = "<start>")
sentence = grammar[nonterm].sample.join(' ')
while sentence.has_placeholder? do
sentence.sub!(/(<\w+>)/){grammar[$1].sample.join(' ')}
end
sentence
end
答案 1 :(得分:2)
这是一个快速实现,我使用symbols
代替<>
字符串但您可以更改它以便在需要时轻松处理。
$grammar = {
:start => [["The", :object, :verb, "tonight."]],
:object => [["waves"], ["big", "yellow", "flowers"], ["slugs"]],
:verb => [["sigh", :adverb], ["portend", "like", :object],
["die", :adverb]],
:adverb => [["warily"], ["grumpily"]]
}
def generate_sentence key
return key if key.class == String
$grammar[key].sample.map {|word| generate_sentence word}.flatten
end
3.times do
puts generate_sentence(:start).join(" ")
end
输出:
The big yellow flowers sigh warily tonight.
The slugs die warily tonight.
The big yellow flowers portend like slugs tonight.
答案 2 :(得分:2)
我的理解是所有哈希值都是数组,并且随机选择这些数组的元素。如果随机选择的元素是一个数组,则该数组中包含的所有单词都将在句子中使用,该数组中的任何散列键都将被该散列键值的随机选择元素替换,依此类推。
<强>代码强>
def random_words(h, key)
h[key].map { |obj| recurse(h,obj) }.join(' ')
end
def recurse(h, obj)
case obj
when Array
obj.map { |o| recurse(h, o) }
when /\<.+?\>/
recurse(h, h[obj].sample)
else
[obj]
end
end
<强>实施例强>
示例1
h = { "<start>" =>[["The", "<object>", "<verb>", "tonight."]],
"<object>"=>[["waves"], ["big", "yellow", "flowers"], ["slugs"]],
"<verb>" =>[["sigh", "<adverb>"], ["portend", "like", "<object>"],
["die", "<adverb>"]],
"<adverb>"=>[["warily"], ["grumpily"]]
}
random_words(h, "<start>")
#=> "The waves portend like slugs tonight."
random_words(h, "<start>")
#=> "The big yellow flowers sigh warily tonight."
random_words(h, "<start>")
#=> "The slugs die warily tonight."
random_words(h, "<object>")
#=> "waves big yellow flowers slugs"
random_words(h, "<verb>")
#=> "sigh warily portend like waves die warily"
random_words(h, "<adverb>")
#=> "warily grumpily"
示例2
h = { "<start>" =>[["The", "<object>", "<verb>", "tonight."]],
"<object>"=>[["waves"], ["big", "<verb>", "yellow", "flowers"], ["slugs"]],
"<verb>" =>[["sigh", "<adverb>"], ["portend", "like", "<object>"],
["die", "<start>", "<adverb>"]],
"<adverb>"=>[["warily", "<object>"], ["grumpily"]]
}
random_words(h, "<start>")
#=> "The big sigh grumpily yellow flowers die The waves sigh grumpily \
# tonight. grumpily tonight."
random_words(h, "<start>")
#=> "The big die The big die The slugs sigh grumpily tonight. grumpily \
# yellow flowers die The big sigh warily slugs yellow flowers die The \
# slugs die The slugs portend like big portend like big sigh grumpily \
# yellow flowers yellow flowers tonight. grumpily tonight. grumpily \
# tonight. warily waves tonight. warily big die The slugs sigh warily \
# big sigh grumpily yellow flowers tonight. warily big portend like big \
# portend like waves yellow flowers yellow flowers yellow flowers yellow \
# flowers sigh warily waves tonight."
示例3
h = { "<g1>"=>[["It", "<g2>", "<g3>", "..."]],
"<g2>"=>[["of"], ["waves"], ["was the", "<g3>", "<g4>", "<g3>"],
["wisdom,"], ["foolishness,"]],
"<g3>"=>[["<g4>", "of", "<g2>"], ["it", "<g2>"]],
"<g4>"=>[["best"], ["worst"], ["age"], ["times,"]]
}
random_words(h, "<g1>")
#=> "It of it was the it was the it was the times, of foolishness, times, \
# it wisdom, best best of was the it of times, it was the times, of of \
# best it waves worst age of waves ..."
random_words(h, "<g1>")
#=> "It was the best of times, it was the worst of times, it was the age of \
# wisdom, it was the age of foolishness...
答案 3 :(得分:1)
def sentence_generator(hash)
verby = hash["<verb>"].sample.map do |string|
string = hash[string].nil? ? string : hash[string].sample.sample
end.join(" ")
hash["<start>"][0][0] + " " + hash["<object>"].sample.sample + " " + verby + " " + hash["<start>"][0][3]
end
此方法应该为您完成工作。它可以使用一些小的重构,所以你可以调查一下。我希望它有所帮助