繁体   English   中英

如何使用PHP以任何顺序(12个字母,其中6个应该形成一个单词)进行字符搜索?

[英]How to do a character search in any order (12 letters from which 6 should form a word) with PHP?

我整天都在考虑这个问题,似乎无法找到一种有效且快速的记忆方式。 问题是:

例如,我有这些字母:efjlnrrttuwx(12个字母)

我在找这个单词TURTLE(6个字母)

如何使用php查找全范围内所有可能的单词(12个单词)? (或者使用python,如果这可能会容易得多?)

我试过的事情:

  • 使用置换:我使用置换算法使所有字符串成为可能,将它们放入数组(只有6个字符长)并执行in_array以检查它是否与我的数组中的一个字匹配有效字(在这种情况下,包含TURTLE,但有时两三个字)。 这种计算需要花费大量的内存和时间,特别是有6个以上的字符来获得排列。

  • 创建一个正则表达式(我很擅长这个)。 我想创建一个正则表达式来检查12个(输入)字符中的6个是否来自“有效数组”中的单词。 问题是,我们不知道12中的哪个字母将是起始位置和其他字的位置。

这方面的一个例子是: http//drawsomethingwords.net/

我希望你能帮助我解决这个问题,因为我真的想解决这个问题。 谢谢你所有的时间:)

我在编写填字游戏编辑器时遇到了类似的问题(例如,在第二个位置找到长度为5且“B”的所有单词)。 基本上它归结为:

  • 处理单词列表并按长度组织单词(即,长度为2,长度为3,长度为4等所有单词的列表)。 原因是您经常知道要搜索的单词的长度。 如果要搜索未知长度的单词,可以再次重复搜索不同的单词列表。
  • 将每个单独的单词列表插入到第三个搜索树中 ,这样可以更快地搜索单词。 树中的每个节点都包含一个字符,您可以下降树来搜索单词。 还有专门的数据结构,如trie,但我尚未探索过。

现在针对您的问题,您可以使用搜索树来编写搜索功能,例如

function findWords($tree, $letters) {
   // ...
}

其中tree是包含您要搜索的长度的单词的搜索树,而letters是有效字符的列表。 在您的示例中, letters将是字符串efjlnrrttuwx

搜索树允许您一次搜索单词,一个字符,并且可以跟踪到目前为止遇到的字符。 只要这些字符在有效字母列表中,您就会继续搜索。 在搜索树中遇到叶节点后,您已找到可添加到结果中的现有单词。 如果您遇到的字符不是letters (或已经使用过),您可以跳过该字并继续搜索搜索树中的其他位置。

我的填字游戏编辑器Palabra包含上述步骤的实现(一部分在Python中完成,但主要在C中完成)。 它的工作速度足够快,Ubuntu的默认单词列表包含大约70K字。

可能有更好的方法,但这只是我的头脑:

我假设你有一个单词数据库(即字典)。 将字段az添加到数据库表。 编写一个脚本,总结单词中每个字母的计数,并将它们作为整数写入az字段。 IE用于气球,表格如下:

id    name       a    b  ...  l  ...  n  ...  o
1     balloon    1    1       2  ...  1  ...  2

然后,当用户输入单词时,您可以计算该单词中每个字符的数量,并将其与数据库进行匹配。

// User enters 'zqlamonrlob'
// You count the letters:
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
1 1 0 0 0 0 0 0 0 0 0 2 1 1 2 0 1 1 0 0 0 0 0 0 0 1

// Query the database
$sql = "SELECT `name` FROM `my_table` WHERE `a` <= {$count['a'] AND `b` <= {$count['b'] ...}";

这将为您提供使用用户输入的部分或全部字母的单词列表。

这是一个正则表达式,只是为了表明它可以 (但不一定应该 )完成:

preg_match('/^(?:t()|u()|r()|t()|l()|e()|.)+$\1\2\3\4\5\6/i', 'efjlnrrttuwx')

火柴。

它是如何工作的? 如果前面的字母匹配,则空捕获括号始终匹配。 正则表达式末尾的反向引用确保每个角色都参与了比赛。 因此,

preg_match('/^(?:t()|u()|r()|t()|l()|e()|.)+$\1\2\3\4\5\6/i', 'efjlnrrtuwx')

(正确)将不匹配,因为字符串中只有一个t但正则表达式需要两个不同的t s。

问题是当然正则表达式引擎必须检查许多排列才能得出这个结论。 虽然成功匹配可能相当快(第一种情况下正则表达式引擎的175步),但不成功的匹配尝试可能很昂贵(在第二种情况下为3816步)。

我认为你需要从相反的方向解决这个问题。

循环显示单词列表,测试具有指定字符数的单词,以查看单词字符是否在指定的字符集中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM