对字谜求解器实施空白平铺搜索的最佳实践
Posted
技术标签:
【中文标题】对字谜求解器实施空白平铺搜索的最佳实践【英文标题】:Best practice to implement blank tile search to anagram solver 【发布时间】:2013-06-20 06:51:33 【问题描述】:我的网站上目前有一个运行良好且快速的字谜求解器。
我使用数组结构来保存每个单词中使用的每个字母的数值。所以基本上当有人输入字母“fghdywkjd”时,我的求解器将遍历其数据库中的每个单词,并将每个单词中的字母数量与与输入的字母相关的值相匹配,即。 "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”等等.每一个词都将是巨大的。
有什么想法吗?
【问题讨论】:
【参考方案1】:我可能会这样做。我会像这样设置单词数据库表结构:(这样做的主要原因是速度。我们可以按每个查询的字母拆分名称,但我认为这种方式更快,尽管我没有进行基准测试)。
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;
如果您想查看您正在检查的单词与数据库中所有单词之间的区别,请去掉 where 和 having 子句。
让我知道这对你有什么影响。
【讨论】:
伟大的思想都一样 :) 我的表结构就是这样 :) 我对您的代码进行了一点修正 .= 而不是 =。使用单词集效果很好,只是它只提取了可能带有 SET 的单词再加一个,所以它只有 4 个字母的单词。将所有可能的单词“SET”与添加的通配符一起提取出来怎么样? 这将包括 2 到 12 个字母的单词 btw 您可以将 $numberOfWildcards 更改为 $maxWildcards 然后将 WHERE 和 HAVING 更改为<=
而不是 =
在某些情况下有所帮助,但不是全部。例如,访问我的网站freescrabbledictionary.com 并输入字母“settingz”,我可以从这些字母中获得 111 个单词。使用上面的脚本,它只得到 3 个单词('SETTING'、'TESTING'、'ZESTING')。我不明白 ABS 是否与它有关,但为什么 ABS 以负数列出。正负都无所谓,反正都是绝对的?
好的,我想我现在理解得更多了,我认为问题在于“difference = 1” 因为我使用字母“settingz”,所以它正在寻找包含除至少 1 个字母差异之外的所有单词的单词. “SETTING”的差异为 1。由于没有可以创建差异为 0 的单词,因此没有列出任何单词。所以问题是它必须包含“至少”任何字母。不必包含每个字母。有道理?对不起,我打字,因为我认为 LOL。会更乱的。任何输入都会很棒......以上是关于对字谜求解器实施空白平铺搜索的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章