2016-10-30 5 views
4

В настоящее время я работаю над проектом, где, используя правила свободной грамматики контекста, я буду генерировать случайные предложения. Прямо сейчас, я работаю над созданием функции, которая будет принимать хеш, и пересекаю ее, выбирая правильные постановки, чтобы создать предложение и вернуть его как строку.Создание строки с карты

Например, если хэш следующего формата:

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

я должен быть способен генерировать случайное предложение, например: «Волны умирают ворчливо сегодня».

Вот общий процесс создания этого предложения:

  1. Он всегда будет начать генерировать на <start> тег и продолжить заполнение необходимых производств.
  2. Он проходит через <start> и добавляет «The», а затем попадает «<object>», поэтому он переходит в ключ <object> и захватывает случайное значение оттуда, например ["waves"].
  3. После этого он возвращается и продолжает перемещаться и натыкается на «<verb>», поэтому он переходит в ключ <verb> и захватывает случайное значение оттуда, например ["die", "<adverb>"].
  4. Поскольку он столкнулся с «<adverb>», он должен войти в ключ <adverb> и выбрать случайное значение, например [«сердито»].
  5. Затем он возвращается к пересечению и натыкается на него и добавляет «сегодня». Он достиг конца <start>, чтобы он мог выводить предложение сейчас.

Как написать метод случайного генерирования предложений?

+3

Ваш вопрос преждевременно. Вы должны попробовать, тогда, когда вы не можете понять это, покажите нам, как вы пытались решить «# TODO: ваша реализация здесь» с подробным вопросом о конкретной проблеме, с которой вы столкнулись, вместо того, чтобы спросить нас, как написать код. «[Сколько ожиданий от пользователей Stack Overflow?] (Http://meta.stackoverflow.com/q/261592)« –

+0

Я не прошу решения, я изучаю рубин в течение 2 недель и Я не знаю, как это сделать в рубине. Если бы это было сделано на Java, у меня не было бы столько проблем с записью этой функции. –

ответ

4

Удовольствие!

После определения String # 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.times внутри декларации метода? Я пытаюсь использовать метод def expand (grammar, non_term = "") для выполнения всего этого. – FlameDra

+0

Цикл 3.times - это просто, чтобы получить 3 разных примера. –

+0

Я обновил свой ответ методом расширения. –

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... 
Смежные вопросы