是递归解决方案吗? - Python

时间:2014-09-22 11:15:50

标签: python algorithm recursion

我试图找出使用Mendeelev表拼写哪些单词。例如,单词" helico"可以拼写为He Li C O(氦 - 锂 - 碳 - 氧),也可以作为He Li Co(氦 - 锂 - 钴)。 我写了一个小程序来做这件事。我在word_list中有单词(" helico","可爱"依此类推),元素在元素中(" H He Li" ...) 我使用了一个递归,因为我虽然可以接受一个单词,但在单词的开头查找一个元素,将其删除,然后用较短的单词重新启动该过程。如果单词结束为空,则表示它是可拼写的。 它有效,但问题是,一旦我找到第一个解决方案(He Li C O),我发现很难回到下一个解决方案 - He Li Co 由于递归," helico"已成为" co"我会找到Co,但已经忘记了"第一部分(何力)

我的感觉是,因为每个单词可能有多种解决方案,所以递归不适合。

有什么想法?我不是在寻找解决方案,而是为了帮助我解决这个问题......

def search_element(startword, match):
    print startword," MATCH IS",match
    if startword =="":
        print match, "empty startword"
        match =""
    for elem in elements:
        #print elem,
        if elem == "$$":
            match =""
        if startword.startswith(elem):
            newword = startword.replace(elem,"",1)
            match = match +" "+ elem
            #print startword, elem, match, "----", newword
            match = search_element(newword, match)
    return(match)


elements = ['h', 'he', 'li', 'be', 'b', 'c', 'n', 'o', 'f', 'ne', 'na', 'mg', 'al', 'si', 'p', 's', 'cl', 'ar', 'k', 'ca', 'sc', 'ti', 'v', 'cr', 'mn', 'fe', 'co', 'ni', 'cu', 'zn', 'ga', 'ge', 'as', 'se', 'br', 'kr', 'rb', 'sr', 'y', 'zr', 'nb', 'mo', 'tc', 'ru', 'rh', 'pd', 'ag', 'cd', 'in', 'sn', 'sb', 'te', 'i', 'xe', 'cs', 'ba', 'la', 'ce', 'pr', 'nd', 'pm', 'sm', 'eu', 'gd', 'tb', 'dy', 'ho', 'er', 'tm', 'yb', 'lu', 'hf', 'ta', 'w', 're', 'os', 'ir', 'pt', 'au', 'hg', 'tl', 'pb', 'bi', 'po', 'at', 'rn', 'fr', 'ra', 'ac', 'th', 'pa', 'u', 'np', 'pu', 'am', 'cm', 'bk', 'cf', 'es', 'fm', 'md', 'no', 'lr', 'rf', 'db', 'sg', 'bh', 'hs', 'mt', 'ds', 'rg', 'cp', 'uut', 'uuq', 'uup', 'uuh', 'uus', 'uuo', '$$']
word_list =['helico', 'cute']


for word in word_list:
    match=""
    search_element(word, match)

2 个答案:

答案 0 :(得分:0)

我认为递归很适合这个问题。我们暂时把Uu *元素放在一边,这样我们就有一两个字母的块。可能的安排数量随着单词的长度呈指数增长。你有10个字母单词的可能性不到100种,但20个单字的单词却超过10,000种。

但是:你不必考虑所有这些可能性。如果使用递归,则可以避免使用死枝。所以,假设你想要返回一个组合列表。

  • 从原始字w
  • 开始
  • 这个词是空的:然后我们找到了一个字符串。
  • 第一个字母是有效的元素符号吗?保存w[1:]并使用w[1:]
  • 递归
  • 前两个字母是有效的元素符号吗?保存w[2:]并使用w[2:]
  • 递归
  • 将合并的结果返回一级

当然,到目前为止,您必须想出一种存储结果的方法。例如,您可以在每次递归时使用连字符构建一个字符串,并在递归命中空字时返回一个仅包含该字符串的列表。

这比生成所有组合然后检查它们是否是有效元素要好得多。我的示例实现在不到半秒的时间内拆分了大约50,000个单词的字典。

顺便说一句,您应该使用集合或字典而不是列表来存储元素符号。

答案 1 :(得分:0)

这是递归的典型案例。这是一个示例代码:

def findall(word, elements):
    def sub(word, res):
        if word:
            for elt in elements:
                if word.startswith(elt):
                    yield from sub(word[len(elt):], res+[elt])
        else:
            yield res
    yield from sub(word, [])

测试:

for word in word_list:
    for res in findall(word, elements):
        print(word, res)

产量

helico ['he', 'li', 'c', 'o']
helico ['he', 'li', 'co']
cute ['c', 'u', 'te']
cute ['cu', 'te']