Я сталкивался с подобными проблемами при написании редактора кроссвордов (например, найти все слова длиной 5 с буквой B во второй позиции).В основном это сводится к:
- Обработка списка слов и упорядочение слов по длине (т. Е. Список всех слов длиной 2, длиной 3, длиной 4 и т. Д.).Причина в том, что вы часто знаете длину слова, которое вы хотите найти.Если вы хотите найти слова неизвестной длины, вы можете повторить поиск для другого списка слов.
- Вставьте каждый отдельный список слов в третичное дерево поиска , которое значительно ускоряет поиск слов.Каждый узел в дереве содержит символ, и вы можете спуститься по дереву для поиска слов.Существуют также специализированные структуры данных, такие как trie , но я (пока) не исследовал.
Теперь для вашей проблемы вы можете использовать дерево поиска для написания функции поиска.например,
function findWords($tree, $letters) {
// ...
}
, где tree
- это дерево поиска, содержащее слова нужной длины, а letters
- список допустимых символов.В вашем примере letters
будет строкой efjlnrrttuwx
.
Дерево поиска позволяет вам искать слова, по одному символу за раз, и вы можете отслеживать символы, с которыми вы встречались до сих пор.Пока эти символы находятся в списке допустимых букв, вы продолжаете поиск.Как только вы встретили листовой узел в дереве поиска, вы нашли существующее слово, которое вы можете добавить к результату.Если вы встретите персонажа, которого нет в letters
(или он уже был использован), вы можете пропустить это слово и продолжить поиск в другом месте дерева поиска.
Мой редактор кроссвордов Palabra содержит реализацию вышеописанных шагов (часть выполнена на Python, но в основном на C).Он работает достаточно быстро для стандартного списка слов в Ubuntu, содержащего примерно 70 тыс. Слов.