所以我有一个3到20个字符长的单词数据库。我想用PHP编写一些代码,以查找包含在较大单词中的所有较小单词。例如,在“向内”一词中,有“雨”,“赢”,“骑”等词。
最初,我考虑将一个字段添加到Words表中(Words3至Words20,表示单词中字母的数目),例如“ LetterCount”……例如,“ rally”将表示为10000000000200000100000010:字母A,字母B的0个实例,字母L的2个实例,等等。然后,遍历每个表中的所有单词(如果指定了找到的单词的目标长度,则遍历一个表)并比较每个单词的LetterCount到源单词的LetterCount(在上面的示例中为“向内”)。
但是后来我开始考虑到,这将给MySQL数据库和PHP脚本造成太大的负担,调用每个单词的LetterCount,将每个数字与源单词的数字进行比较,等等。
有没有更简单,也许更直观的方式来做到这一点?如果对存储过程有任何帮助,我愿意使用存储过程。只是一些建议将不胜感激。谢谢!
最佳答案
这是一个简单的解决方案,应该会非常有效,但是只能处理一定大小的单词(可能会分解大约15-20个字符,具体取决于组成单词的字母是否为具有较低值的低频字母)或具有较高值的高频字母):
根据频率为每个字母分配一个质数。因此,e
是2,t
= 3,a
= 5,等等,使用来自here或某些类似来源的频率值。
通过乘以单词中字母的质数来预先计算单词列表中每个单词的值,并将其存储在表中的bigint
数据类型列中。例如,tea
的值为3*2*5=30
。如果单词中有重复的字母,请重复该因子,以便teat
的值应为3*2*5*3=90
。
当检查一个词(例如rain
)是否包含在另一个词(例如inward
)内部时,检查rain
的值是否除以inward
的值就足够了。在这种情况下,inward = 14213045
,rain = 7315
和14213045
可被7315
整除,因此单词rain
在单词inward
内。
bigint列在9223372036854775807
处最大,最多可以包含15-20个字符(取决于单词中字母的频率)。例如,我从here的第一个20个字母的单词(即anitinstitutionalism
)中提取了一个值,该值的6901041299724096525
刚好适合bigint列。但是,由14个字母组成的单词xylopyrography
的值635285791503081662905
太大。您可能需要使用替代方法来处理非常大的特殊情况,但希望其中的少数几个仍然相对有效。
该查询的工作方式类似于我在此处准备的演示:http://www.sqlfiddle.com/#!2/9bd27/8
关于php - 难题解决:在PHP中查找较大词中的所有词,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10096744/