PYTHON-给定一个起始单词,哪个字母序列将允许您最大化可以拼写的有效单词数

PYTHON-给定一个起始单词,哪个字母序列将允许您最大化可以拼写的有效单词数,python,algorithm,trie,Python,Algorithm,Trie,编辑:新问题。考虑到我怀疑这个问题比我最初想象的更难——可能是NP复杂,我有一个不同的问题:什么是有用的算法,可以接近最大化使用的字母数 我受启发写了一个基于纸牌游戏拼字游戏Slam的程序!然而,我对算法还不熟悉,想不出一种有效的方法来解决这个问题: 您可以从一个字符串开始,该字符串包含一个英语有效的4个字母的单词。您可以一次在该单词上放置一个字母,这样,通过放置该字母,您可以形成一个新的字典有效单词。您拥有的字母与字母表中的字母相等 例如,如果起始词是“购物车”,则这可能是一个有效的移动序列:

编辑:新问题。考虑到我怀疑这个问题比我最初想象的更难——可能是NP复杂,我有一个不同的问题:什么是有用的算法,可以接近最大化使用的字母数

我受启发写了一个基于纸牌游戏拼字游戏Slam的程序!然而,我对算法还不熟悉,想不出一种有效的方法来解决这个问题:

您可以从一个字符串开始,该字符串包含一个英语有效的4个字母的单词。您可以一次在该单词上放置一个字母,这样,通过放置该字母,您可以形成一个新的字典有效单词。您拥有的字母与字母表中的字母相等

例如,如果起始词是“购物车”,则这可能是一个有效的移动序列:

沙地-->sane-->正弦-->直线-->lins-->管脚-->散热片等

目标是通过使用尽可能多的字母表中的字母(而不是一个字母多次使用),最大限度地增加序列中的单词数量

我的算法找不到最长的序列,只是猜测最长的序列可能是什么

首先,它得到一个列表,其中列出了通过更改起始单词的一个字母可以形成的所有单词。该列表称为“邻接列表”。然后它会查看邻接列表中的所有单词,并找出其中哪个单词的相邻单词最多。无论哪个单词的邻接词最多,它都会选择将起始词转换为

例如,sane这个词可以转换成28个其他单词,sine这个词可以转换成27个其他单词,line这个词可以转换成30个其他单词——每一个选择都是为了最大限度地提高拼写越来越多单词的可能性

解决这个问题的最好办法是什么?什么样的数据结构是最佳的?如何改进代码,使其更高效、更简洁

##Returns a list of all adjacent words.  Lists contain tuples of the adjacent word and the letter that
##makes the difference between those two words.

def adjacentWords(userWord):
    adjacentList, exactMatches, wrongMatches = list(), list(), str()
    for dictWords in allWords:
        for a,b in zip(userWord, dictWords):
            if a==b: exactMatches.append(a)
            else: wrongMatches = b
        if len(exactMatches) == 3:
            adjacentList.append((dictWords, wrongMatches))
        exactMatches, wrongMatches = list(), list()
    return adjacentList
    #return [dictWords for dictWords in allWords if len([0 for a,b in zip(userWord, dictWords) if a==b]) == 3]


def adjacentLength(content):
    return (len(adjacentWords(content[0])), content[0], content[1])

#Find a word that can be turned into the most other words by changing one letter
def maxLength(adjacentList, startingLetters):
    return max(adjacentLength(content) for content in adjacentList if content[1] in startingLetters)

def main():
    startingWord = "sand"
    startingLetters = "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z".replace(" ", "").split(',')

    existingWords = list()
    while True:
        adjacentList = adjacentWords(startingWord)
        letterChoice = maxLength(adjacentList, startingLetters)
        if letterChoice[1] not in existingWords:
            print "Going to use letter: "+ str(letterChoice[2]) + " to spell the word "+ str(letterChoice[1]) + " with "+ str(letterChoice[0]) + " possibilities."
            existingWords.append(letterChoice[1])
            startingLetters.remove(str(letterChoice[2]))
            startingWord = letterChoice[1]


main()
@Parseltongue 您可能会发现,虽然给定的任务有一个最优的解决方案,但是没有已知的方法以最优的方式解决它。这项任务是问题之一

考虑这一点:

sand --> [?]and 
此时,您必须迭代所有可能的
[?]和
组合,以找出符合条件的单词。在最坏的情况下,没有启发式,即26次迭代

sand --> band, hand, land, wand
现在,记下找到的每个单词并重复第二个字母等。
您可以看到,您必须进行的迭代量呈指数增长


这在某种程度上与国际象棋的问题非常相似。无论你的电脑有多强大,它都无法预测所有可能的移动,因为组合太多了

我和一个朋友在一次数据结构和算法课程的实验中开发了一个类似的程序(尽管是Java)。任务是创建从一个单词到另一个单词的最短单词链

我们建立了一个包含所有可用单词的树,其中一个节点连接到另一个节点,如果它们只相差一个字母。为了提高速度,需要使用某种哈希表,如字典。实际上,我们从用作键的单词中删除了一个字母,从而利用了这样一个事实,即连接的单词具有相同的哈希,但是如果没有代码,很难解释

为了找到最短的链,我们只使用了广度优先搜索。然而,在图中查找最短路径比查找最长路径更容易。有关更多详细信息,请参阅


要解决主要问题,您可以迭代所有单词。然而,如果速度很重要,那么通常更容易找到一个好的特殊启发式算法。

-1这不是一个真正的问题。需要更清楚。气味[虽然我不确定]BFS将解决问题,但会消耗大量时间。BFS和DFS只访问一次节点,因此它们不适合此任务。此外,每个字母只能使用一次。假设一个问题是NP完全问题与实际知道(证明)它是NP完全问题之间存在巨大差异。@Yiu H BasicWolf将问题表示为一个具有所有可能性的图(树)。从给定的单词图中,问题是找到最长的路径。这个问题是NP_难的。数据表示决定了可实现的算法复杂度。这就是为什么我们为每个任务选择适当/不同的数据表示形式。他没有说所有可能组合的图树都是NP完全的。他首先说它是NP完全的,然后给出了数据表示法。yi_H,你能给出解决这类问题的另一种方法吗?很明显,该结构扩展为一棵树。