当前位置: 首页 > 面试题库 >

如何从字母矩阵中找到可能的单词列表[Boggle Solver]

徐景明
2023-03-14
问题内容

最近,我一直在iPhone上玩一个名为Scramble的游戏。你们中有些人可能将此游戏称为Boggle。本质上,当游戏开始时,您会得到一个字母矩阵,如下所示:

F X I E
A M L O
E W B X
A S T U

游戏的目标是找到尽可能多的单词,这些单词可以通过将字母链接在一起来形成。您可以从任何字母开始,并且包围它的所有字母都是公平的游戏,然后转到下一个字母时,包围该字母的所有字母都是公平的游戏,除了以前使用的任何字母。因此在上面的网格,例如,我能想出的话LOB,TUX,SEA,FAME,等词必须至少有3个字符,并且不超过N×N个字符,这将是本场比赛16,但可以在一些实现改变。尽管这款游戏既有趣又令人上瘾,但我显然并不擅长于此,我想通过编写一个程序给我一些欺骗,该程序将为我提供尽可能最好的单词(单词越长,您获得的积分就越多)。

样本虫
(来源:boggled.org)

不幸的是,我对算法或其效率等不是很好。我的第一次尝试是使用诸如此类的字典(〜2.3MB),并进行线性搜索以尝试将组合与字典条目匹配。这需要很长时间才能找到可能的单词,并且由于您每轮只能得到2分钟,因此这根本不够用。

我很想看看是否有任何Stackoverflowers可以提出更有效的解决方案。我主要在寻找使用Big 3 P的解决方案:Python,PHP和Perl,尽管Java或C ++的任何功能也很酷,因为速度至关重要。

当前解决方案:

  • 亚当·罗森菲尔德(Adam Rosenfield),Python,约20秒
  • John Fouhy,Python,大约3秒
  • Kent Fredric,Perl,〜1秒
  • Darius Bacon,Python,〜1秒
  • rvarcher,VB.NET (实时链接),〜1s
  • Paolo Bergantino,PHP (实时链接),〜5s(本地〜2s)

问题答案:

我的答案与此处的其他答案一样工作,但我将其发布,因为它比设置其他字典更快,看起来比其他Python解决方案要快。(我对照John Fouhy的解决方案对此进行了检查。)设置之后,解决的时间减少了。

grid = "fxie amlo ewbx astu".split()
nrows, ncols = len(grid), len(grid[0])

# A dictionary word that could be a solution must use only the grid's
# letters and have length >= 3. (With a case-insensitive match.)
import re
alphabet = ''.join(set(''.join(grid)))
bogglable = re.compile('[' + alphabet + ']{3,}$', re.I).match

words = set(word.rstrip('\n') for word in open('words') if bogglable(word))
prefixes = set(word[:i] for word in words
               for i in range(2, len(word)+1))

def solve():
    for y, row in enumerate(grid):
        for x, letter in enumerate(row):
            for result in extending(letter, ((x, y),)):
                yield result

def extending(prefix, path):
    if prefix in words:
        yield (prefix, path)
    for (nx, ny) in neighbors(path[-1]):
        if (nx, ny) not in path:
            prefix1 = prefix + grid[ny][nx]
            if prefix1 in prefixes:
                for result in extending(prefix1, path + ((nx, ny),)):
                    yield result

def neighbors((x, y)):
    for nx in range(max(0, x-1), min(x+2, ncols)):
        for ny in range(max(0, y-1), min(y+2, nrows)):
            yield (nx, ny)

用法示例:

# Print a maximal-length word and its path:
print max(solve(), key=lambda (word, path): len(word))

编辑:筛选出少于3个字母的单词。

编辑2:我很好奇为什么Kent Fredric的Perl解决方案更快?原来是使用正则表达式匹配而不是字符集。在Python中执行相同的操作可使速度提高一倍。



 类似资料:
  • 问题内容: 我有一个类似的名字列表: 以及文档列表,在每个文档中都提到了其中一些名称。 我想获得输出作为共现矩阵,例如: R中有一个解决此问题的方法(创建共现矩阵),但我无法在Python中做到这一点。我正在考虑在Pandas进行此操作,但没有任何进展! 问题答案: 显然,可以根据您的目的进行扩展,但是它会执行以下常规操作:

  • 我有一个包含50000个单词的单词列表,还有一个逐行查找字母字符的txt文件。我试图通过按顺序阅读单词列表中的单词来找到包含7个不同字母的单词,我为此编写了一个方法。 首先,我浏览单词并同步字符列表,然后通过导航字母txt文件在单词中相互检查,如果有,则增加计数器。通过这种方式,我试图了解单词中有多少不同的字母,最后,如果它提供了控制,我会将其添加到列表中。 读取txt文件并返回哈希集。 但它不是

  • 我试图显示以用户输入的字母开始的单词列表。 因此,例如,如果我在我的列表中添加了三个词,cat、玉米和dog,并且用户输入了字母c,那么Java小程序上的输出应该是cat、玉米。 但是,我不知道该怎么做。 正在将所有用户输入添加到秘密存储的列表中,我现在想在按下时制作另一个按钮,以显示用户以指定字母开头的单词。

  • 基于当前的实现,我将从某个来源获得一个数组列表,其中包含大约1000个按字母排序的唯一名称(A-Z或Z-A)。 我需要找到以给定字母表开头的第一个单词的索引。 因此,更准确地说,当我选择一个字母表,例如“M”时,它应该给我排序列表中以“M”开头的单词第一次出现的索引。 这样我就可以找到26个字母中每个字母开头的所有单词的索引。 请帮我找到一个不影响速度的解决方案。 更新时间: 实际上,在获得100

  • 我想在不同的列表中加入多个向量,并输出一个矩阵列表。其思想是,列表中具有相同名称的所有项目,例如所有项目,通过行作为矩阵连接起来。增加的复杂性是,这些向量可以具有不同的长度,因此实现起来并不简单;矩阵中缺少的值可以附加s。 输入列表: 我希望获得的理想输出是一个列表,其中矩阵的数量与唯一列表项的数量相同,其中每个矩阵由行绑定的不同长度的向量组成: 我将如何编写一个函数,它也可以扩展到合并具有不同长

  • 很少的要求。 在发布你的答案之前,请!! 确保函数不会对其他数据产生错误,模拟几个类似的矩阵。(关掉种子) 确保你的功能比我的快 确保你的函数和我的完全一样,在不同的矩阵上模拟它(关闭种子) 举个例子 目前我已收到多达5个答案,但没有一个适合上述任何一点: ======================================================函数在逻辑矩阵的第一列中查找,如果