2016-10-30 7 views
4

現在、コンテキストフリーの文法ルールを使用して、ランダムな文章を生成するプロジェクトに取り組んでいます。今、私は、ハッシュを取り、正しいプロダクションを選んで文を作成し、それを文字列として返す関数を作成しています。マップから文字列を作成する

{ 
"<start>"=>[["The", "<object>", "<verb>", "tonight."]], 
"<object>"=>[["waves"], ["big", "yellow", "flowers"], ["slugs"]], 
"<verb>"=>[["sigh", "<adverb>"], ["portend", "like", "<object>"], ["die", "<adverb>"]], 
"<adverb>"=>[["warily"], ["grumpily"]] 
} 

は、Iのような、ランダムな文を生成することができなければならない:「波がgrumpily今夜ダイ」は、以下の形式のハッシュ所与例えば

、。ここで

は、この文を生成するための全体的なプロセスである:

  1. それは常に<start>タグで生成を開始し、必要な生産を埋めていきます。
  2. これは<start>を通過し、 "The"は "<object>"になりますので、<object>キーに入り、["waves"]などのランダムな値を取得します。
  3. その後、トラバースを続行し、 "<verb>"にわたり、<verb>キーに入り、そこからランダムな値を取得します(["die", "<adverb>"]など)。
  4. "<adverb>"が発生したので、<adverb>キーに入り、[grumpily]などのランダムな値を選択する必要があります。
  5. それから、それは横断に戻り、出てきて「今夜」を加えます。 <start>の終わりに達したため、今すぐ文を出力できます。

ランダムに文章を生成する方法はありますか?

+3

あなたの質問は時期尚早です。試してみると分かりませんが、あなたが遭遇した特定の問題に関する詳細な質問を使って、あなたの実装方法を#TODO:あなたの実装を解決しようとした方法を教えてください。コード。 "[どのくらいの研究努力がスタックオーバーフローのユーザーに期待されていますか?](http://meta.stackoverflow.com/q/261592)" –

+0

私は解決策を求めていません。今は2週間ルビーを学んでいます。それについてルビーでどうやって行くのか慣れていない。これがJavaで行われるのであれば、この機能を書くのに苦労することはありません。 –

答えて

4

楽しい運動!

ストリング#has_placeholderを定義したら? <と>

の間の単語をチェックするアルゴリズムは、開始文を選択し、プレースホルダが存在する限りそれを繰り返します。プレースホルダが見つかった場合は、ランダムに選択されたサブセンテースに置き換えられます。 エラーをチェックするために何も行われません。一部のプレースホルダは定義されていないか、無限ループが存在する可能性があります。

文字列を返します。異なる深さの配列を持つツリーも返すことができます。

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. 

EDIT:

あなたはこのようになりたい方法:

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 
+2

'Array#sample'は既に発明されています:) –

+0

ありがとう!これはRuby 1.8の遺物です:D –

+0

あなたのコードは、文字列がプレースホルダーかどうかをチェックします(<は最初の文字、最後の文字>)。私のコードは、文字列にプレースホルダが含まれているかどうかをチェックします。 –

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. 
+0

メソッド宣言の中に3回のループがありますか?私は1つのdefを展開しようとしています(文法、non_term = "")メソッドはすべてを行う。 – FlameDra

+0

3倍のループは、3つの異なる例を得るに過ぎません。 –

+0

私は自分の答えをexpandメソッドで更新しました。 –

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 

この方法があなたのために仕事をする必要があります。それは少しリファクタリングを使うことができるので、あなたはそれを見ることができます。私はそれが助けてくれることを願っています。

+0

ありがとう、あなたも同様に働いているようです。 – FlameDra

+0

NPそれは楽しいものでした – Nsoseka

+0

あなたの例は動的ではありませんか?それは文の定義を使用していないようです。 –

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... 
関連する問題