拼图解决:在PHP中查找较大单词中的所有单词

时间:2012-04-10 21:31:22

标签: php string word puzzle scramble

所以我有一个3到20个字符长的单词数据库。我想用PHP编写代码,找到包含在一个更大的单词中的所有较小的单词。例如,在“向内”一词中有“rain”,“win”,“rid”等字样。

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

但后来我开始认为这会对MySQL数据库以及PHP脚本造成太大的负担,调用每个单词的LetterCount,将每个数字与源词的数字进行比较,等等。 / p>

是否有更容易,也许更直观的方式来做到这一点?我愿意使用存储过程,如果它能以任何方式帮助增加开销。只是一些建议将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:6)

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

  1. 根据频率为每个字母指定一个素数。因此,使用here或某些类似来源的频率值,e为2,t = 3,a = 5等。
  2. 通过将单词中字母的素数值相乘,预先计算单词列表中每个单词的值,并将其存储在bigint数据类型列中的表中。例如,tea的值为3*2*5=30。如果某个单词有重复的字母,请重复该系数,以便teat的值为3*2*5*3=90
  3. 检查rain等其他单词中是否包含inward等单词时,只需检查rain的值是否为inward除以{ {1}}。在这种情况下,inward = 14213045rain = 731514213045可以被7315整除,因此单词rain位于单词inward内。< / LI>
  4. bigint列最大值为9223372036854775807,最多约15-20个字符(取决于单词中字母的频率)。例如,我从here获取了第一个20个字母的单词,即anitinstitutionalism,其值为6901041299724096525,几乎不适合bigint列。但是,14个字母的单词xylopyrography的值为635285791503081662905,这个值太大了。您可能必须使用备用方法处理非常大的特殊情况,但希望它们足够少,它仍然相对有效。
  5. 查询可以像我在这里准备的演示一样:http://www.sqlfiddle.com/#!2/9bd27/8