2013-06-23 4 views
2

У меня в настоящее время есть анаграмма-решатель на моем сайте, который работает хорошо и быстро.Лучшая практика для реализации пустого поиска плитки для решения анаграммы

Я использую структуру массива, чтобы удерживать числовые значения каждой буквы, используемые в каждом слове. Таким образом, в основном, когда кто-то вводит буквы «fghdywkjd», мой решатель будет проходить каждое слово в своем db и сопоставлять количество букв в каждом слове с значениями, связанными с введенным буквой, т.е. «Fghdywkjd»

Я строю массив как этот

$a = array('a' => 1, 'b' => 1, 'c' => 1, 'd' => 1, 'e' => 1, 'f' => 1, 'g' => 1, 'h' => 1, 'i' => 1, 'j' => 1, 'k' => 1, 'l' => 1, 'm' => 1, 'n' => 1, 'o' => 1, 'p' => 1, 'q' => 1, 'r' => 1, 's' => 1, 't' => 1, 'u' => 1, 'v' => 1, 'w' => 1, 'x' => 1, 'y' => 1, 'z' => 1); 

Он подсчитывает значения, как она проходит через каждое слово.

Я пытаюсь придумать лучший способ добавить к нему пустую особенность плитки, которая не замедлит ее.

Единственный способ, которым я могу понять, как добавить эту функцию, - это подождать, пока у меня не будет всех моих результатов, затем возьмите каждое найденное слово и добавьте букву «a» и найдите возможности, затем добавьте последнее «b» и так далее на. Для каждого слова, которое было бы огромным.

В любом случае, некоторые идеи?

ответ

2

Вот, наверное, как я это сделаю. Я бы установил структуру таблиц базы данных слов следующим образом: (Основная причина этого - скорость. Мы могли бы разделить имена по буквам на каждый запрос, но я думаю, что этот способ быстрее, хотя я не тестировал).

name a b c d e f g h i j k l m n o p q r s t u v w x y z 
---- - - - - - - - - - - - - - - - - - - - - - - - - - - 
test 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 
tests 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 
foo  0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 

, а затем в PHP я хотел бы сделать это: Это предполагает, что количество букв в слове должно соответствовать анаграмму точно (без дополнительных букв).

<?php 
$letters = array_fill_keys (range('a', 'z'), 0); 

$word = 'set'; // start with the word 'set' 
$wordLetters = str_split(preg_replace("/[^a-z]/", '', strtolower($word))); // remove invalid letters, lowercase, and convert to array 

$numberOfWildcards = 1; // Change this to the number of wildcards you want 

foreach ($wordLetters as $letter) { 
    $letters[$letter]++; 
} 

$query = 'SELECT `name`, 0'; 

foreach ($letters as $letter => $num) { 
    // $query .= "+ABS(`$letter`-$num)"; 
    $query .= "+IF(`$letter` > $num, `$letter` - $num, 0)"; 
} 

$query = ' AS difference 
    FROM `word_table` 
    WHERE 
     LENGTH(`name`) = ' . (strlen($word) + $numberOfWildcards) . ' 
    HAVING 
     difference = ' . $numberOfWildcards; 

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

Сообщите мне, как это работает для вас.

+0

Великие мысли думают одинаково :) Моя структура таблицы в точности такова: я ввел ваш код с небольшим исправлением. = Вместо just =. Использование набора слов работало отлично, за исключением того, что оно только вытягивало возможные слова с помощью SET в нем плюс еще один, так что это были всего лишь 4 буквенных слова. Как насчет того, чтобы вытащить каждое возможное слово «SET», можно сочетать с добавлением диких карточных слов? –

+0

это будет включать от 2 до 12 буквенных слов. Btw –

+0

Возможно, вам придется изменить $ numberOfWildcards на $ maxWildcards, а затем изменить WHERE и HAVING как '<=' вместо '=' – chrislondon