Хареса ми пъзела и ето моето мнение за възможно решение*...
* Въпреки това бих препоръчал следващия път да не зададете въпроса си, без да покажете какво сте опитали и къде сте закъсали... В противен случай може да изглежда, че ни захвърляте домашното си. ..
Да приемем, че това е нашият текст:
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