【问题标题】:Puzzle Solving: Finding All Words Within a Larger Word in PHP解谜:在 PHP 中查找较大单词中的所有单词
【发布时间】:2012-04-10 21:31:22
【问题描述】:

所以我有一个长度在 3 到 20 个字符之间的单词数据库。我想在 PHP 中编写一些代码,以查找包含在较大单词中的所有较小单词。比如“inward”这个词里就有“rain”、“win”、“rid”等词。

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

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

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

【问题讨论】:

    标签: php string word puzzle scramble


    【解决方案1】:

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

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

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

    【讨论】:

    • 这太棒了!我想我可以测试我数据库中 20 个字母的单词中的几个,并找出它们的平均主要产品是什么。但这看起来是一个很好的方法。
    • 将其扩展到 20 个字母的一种方法可能是将单词值分成两部分,一个用于第 1、3、5、7 个字母等,即e, a, n, s, ...,另一个用于第 2、4、6、8 个字母等,即t, i, o, r, ...。然后,您将检查主词的value1 是否可以被列表中某个词的value1 整除,并且主词的value2 是否可以被列表中某个词的value2 整除。这个想法是一样的,除了分成两个数字,你的所有单词更有可能适合 bigint 范围。
    • xylopyrography 的情况下,此方法将生成更易于管理的value1=1030010495value2=10453831141 值。
    • 是的,将字母/质数列表分开,否则您将没有可以划分的标准值。每个值都必须代表相同的可能字母,否则除法将无法正常工作。基本上,我上面描述的第 1、第 3、第 5 等的交错有助于平衡这两个值,因此它们通常会更小且大致相等。
    • 看起来641077061 是素数。我认为您在计算xylopyrography 的值时出现了溢出。我得到的值是整除的,1030010495/59=17457805,和10453831141/15067=693823
    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 2011-09-19
    • 2021-08-27
    • 2012-09-10
    • 2011-02-07
    • 1970-01-01
    • 2015-05-06
    • 2019-08-20
    相关资源
    最近更新 更多