Вам понадобится список слов , например, составленный Project Gutenberg или доступный в источнике для ispell & c.Затем вы можете использовать следующий код для разложения домена на слова:
WORD_LIST = [
'experts',
'expert',
'exchange',
'sex',
'change',
]
def words_that_phrase_begins_with(phrase)
WORD_LIST.find_all do |word|
phrase.start_with?(word)
end
end
def phrase_to_words(phrase, words = [], word_list = [])
if phrase.empty?
word_list << words
else
words_that_phrase_begins_with(phrase).each do |word|
remainder = phrase[word.size..-1]
phrase_to_words(remainder, words + [word], word_list)
end
end
word_list
end
p phrase_to_words('expertsexchange')
# => [["experts", "exchange"], ["expert", "sex", "change"]]
Если задана фраза с нераспознанными словами, она возвращает пустой массив:
p phrase_to_words('expertsfoo')
# => []
Если список слов длинный, это будет медленно.Вы можете сделать этот алгоритм быстрее, предварительно обработав список слов в дереве.Сама предварительная обработка займет время, поэтому, стоит ли оно того, зависит от того, сколько доменов вы хотите протестировать.
Вот некоторый код для преобразования списка слов в дерево:
def add_word_to_tree(tree, word)
first_letter = word[0..0].to_sym
remainder = word[1..-1]
tree[first_letter] ||= {}
if remainder.empty?
tree[first_letter][:word] = true
else
add_word_to_tree(tree[first_letter], remainder)
end
end
def make_word_tree
root = {}
WORD_LIST.each do |word|
add_word_to_tree(root, word)
end
root
end
def word_tree
@word_tree ||= make_word_tree
end
Это создает дерево, которое выглядит следующим образом:
{: c => {: h => {: a => {: n => {: g => {: e => {: word =>true}}}}}},: s => {: e => {: x => {: word => true}}},: e => {: x => {: c => {: h => {: a => {: n => {: g => {: e => {: word => true}}}}}},: p => {: e => {: r => {:t => {: word => true,: s => {: word => true}}}}}}}}
Похоже на Лисп, не так ли?Каждый узел в дереве является хешем.Каждый ключ хеша является либо буквой, значение которой является другим узлом, либо символом: слово со значением true.Узлы с: word - это слова.
Изменение words_that_phrase_begins_with
для использования новой древовидной структуры сделает его быстрее:
def words_that_phrase_begins_with(phrase)
node = word_tree
words = []
phrase.each_char.with_index do |c, i|
node = node[c.to_sym]
break if node.nil?
words << phrase[0..i] if node[:word]
end
words
end