2

所以我有一个长度在 3 到 20 个字符之间的单词数据库。我想在 PHP 中编写一些代码,以查找包含在较大单词中的所有较小单词。例如,在“向内”一词中,有“雨”、“赢”、“摆脱”等词。

起初我考虑在 Words 表中添加一个字段(Words3 到 Words20,表示单词中的字母数),例如“LetterCount”……例如,“rally”将表示为 10000000000200000100000010:1 个实例字母 A,字母 B 的 0 个实例,... 字母 L 的 2 个实例,等等。然后,遍历每个表中的所有单词(如果指定了找到单词的目标长度,则为一个表)并比较每个单词的 LetterCount 到源单词的 LetterCount(上例中的“向内”)。

但后来我开始认为这会给 MySQL 数据库和 PHP 脚本带来过多的负载,调用每个单词的 LetterCount,将每个数字与源词的数字进行比较,等等。

有没有更简单,或许更直观的方法来做到这一点?如果它以任何方式有助于开销,我愿意使用存储过程。只是一些建议将不胜感激。谢谢!

4

1 回答 1

6

这是一个简单的解决方案,应该非常有效,但只能在一定大小的单词范围内工作(可能会分解大约 15-20 个字符,具体取决于组成单词的字母是否是具有较低值的低频字母或具有较高值的​​高频字母):

  1. 根据它的频率为每个字母分配一个质数。e2、t= 3、a= 5 等也是如此。使用此处或类似来源的频率值。
  2. 通过将单词中字母的质数相乘来预先计算单词列表中每个单词的值,并将其存储在表中的bigint数据类型列中。例如,tea将有一个值3*2*5=30。如果一个词有重复的字母,重复这个因子,所以它teat的值应该是3*2*5*3=90
  3. 当检查一个词(例如rain)是否包含在另一个词(例如 )中时,检查 for 的值是否与 for的值相除inward就足够了。在这种情况下,,, 和可以被 整除,所以单词在单词内部。raininwardinward = 14213045rain = 7315142130457315raininward
  4. bigint 列的最大值为9223372036854775807,最多可以包含 15-20 个字符(取决于单词中字母的频率)。例如,我从这里选择了第一个 20 个字母的单词,即anitinstitutionalism, 并且它的值6901041299724096525几乎不能放在 bigint 列中。但是,14 个字母的单词xylopyrography的值为635285791503081662905,太大了。您可能必须使用替代方法将非常大的情况作为特殊情况处理,但希望它们的数量足够少,它仍然会相对有效。

该查询将类似于我在这里准备的演示:http ://www.sqlfiddle.com/#!2/9bd27/8

于 2012-04-10T21:51:27.317 回答