Мне понравилась головоломка, и вот мое видение возможного решения*...
* хотя, я бы порекомендовал вам в следующий раз не просто забрасывать свой вопрос, не показывая, что вы пробовали и где застряли... Иначе может показаться, что вы забрасываете нас своим домашним заданием. ..
Предположим, что это наш текст:
text = 'This is a sentence about pink killer cats chasing madonna.
Sometimes when whales fight bricklayers, everyone drinks champaigne.
You know Madonna has little cats on her slippers.
When whales drink whiskey, your golf game is over.'
Мне кажется, что есть несколько этапов выполнения задач...
Создайте каталог слов.
Подсчитайте, сколько раз каждое слово встречается в тексте.
require 'strscan'
words = {}
scn = StringScanner.new(text.downcase)
( words[scn.matched] = words[scn.matched].to_i + 1 if scn.scan(/[\w]*/) ) while (scn.skip(/[^\w]*/) > 0) || !scn.eos?
Удалите любое слово, которое встречается только один раз — оно не имеет значения.
words.delete_if {|w, v| v <= 1}
разбить текст на строчные предложения.
Сделайте sentences => relevant_words_used
хеш.
sentences = {}
text.downcase.split(/\.[\s]*/).each {|s| sentences[s] = []}
Заполните предложения Hash словами, используемыми в каждом предложении. Ниже приведен упрощенный способ сделать это (в реальном приложении вам нужно будет разделить слова, чтобы слова «кошка» и «гусеница» не перекрывались):
words.each {|w, c| sentences.each {|s, v| v << w if s.include? w} }
пример для более сложной версии:
sentences.each {|s, v| tmp = s.split(/[^\w]+/); words.each {|w, c| v << w if tmp.include? w} }
Ваши группы находятся в массиве sentences.values
. Теперь пришло время найти общие группы и посчитать, сколько раз они повторяются.
common_groups = {}
tmp_groups = sentences.values
until tmp_groups.empty?
active_group = tmp_groups.pop
tmp_groups.each do |g|
common = active_group & g
next if common.empty?
common_groups[common] = [2,(common_groups[common].to_i + 1)].max
end
end
Вуаля, это общие группы:
common_groups.each {|g, c| puts "the word(s) #{g} were common to #{c} sentences."}
# => the word(s) ["is"] were common to 2 sentences.
# => the word(s) ["when", "whales"] were common to 2 sentences.
# => the word(s) ["cats", "madonna"] were common to 2 sentences.
Весь код может выглядеть так:
text = 'This is a sentence about pink killer cats chasing madonna.
Sometimes when whales fight bricklayers, everyone drinks champaigne.
You know Madonna has little cats on her slippers.
When whales drink whiskey, your golf game is over.'
require 'strscan'
text.downcase!
words = {}
scn = StringScanner.new(text)
( words[scn.matched] = words[scn.matched].to_i + 1 if scn.scan(/[\w]*/) ) while (scn.skip(/[^\w]*/) > 0) || !scn.eos?
words.delete_if {|w, v| v <= 1}
sentences = {}
text.split(/\.[\s]*/).each {|s| sentences[s] = []}
# # A better code will split the sentences into words to
# # avoid partial recognition (cat vs. caterpillar).
# # for example:
sentences.each {|s, v| tmp = s.split(/[^\w]+/); words.each {|w, c| v << w if tmp.include? w} }
# # The following is the simplified version above:
# words.each {|w, c| sentences.each {|s, v| v << w if s.include? w} }
common_groups = {}
tmp_groups = sentences.values
until tmp_groups.empty?
active_group = tmp_groups.pop
tmp_groups.each do |g|
common = active_group & g
next if common.empty?
common_groups[common] = [2,(common_groups[common].to_i + 1)].max
end
end
common_groups.each {|g, c| puts "the word(s) #{g} were common to #{c} sentences."}
# => the word(s) ["is"] were common to 2 sentences.
# => the word(s) ["when", "whales"] were common to 2 sentences.
# => the word(s) ["cats", "madonna"] were common to 2 sentences.
ИЗМЕНИТЬ
Я исправил проблему с кодом, из-за которой текст не сохранялся в нижнем регистре. (text.downcase!
против text.downcase
)
ИЗМЕНИТЬ2
Я рассмотрел вопрос о проблемах с частичными словами (например, cat
против caterpillar
или dog
против dogma
)
person
Myst
schedule
24.06.2015