从递归函数返回一个集合

时间:2014-09-04 02:35:16

标签: python recursion

我写了一个简短的程序,显示了DFA的可能输出。因为它是预期的结果。但我一直在尝试重写函数,以便返回结果,而不是使用全局变量 - 我无法弄清楚如何去做。有人可以解释一下如何在不使用全局变量的情况下这样做吗?

result  = set()

def gen_strings(max_length, state = "A", str = ""):
    global result
    if len(str) > max_length:
        return
    if state == "A":
        gen_strings(max_length, "B", str + "0")
        gen_strings(max_length, "C", str + "1")

    elif state == "B":
        gen_strings(max_length, "D", str + "1")

    elif state == "C":
        gen_strings(max_length, "D", str + "0")

    elif state == "D":
        result.add(str)
        gen_strings(max_length, "A", str + "0")
        gen_strings(max_length, "A", str + "1")

2 个答案:

答案 0 :(得分:2)

这里有两个选项:自上而下累积或自下而上。


如果你自下而上,你可以做到这一点,而不需要改变任何东西。这确实使你的递归作为尾调用更难(有时甚至是不可能),但这很好,因为(a)Python无论如何都不会消除尾调用,而且(b)即使它确实如此,你的算法也不会'受益,因为它会进行多次通话。所以,我先说明这一点:

def gen_strings(max_length, state = "A", str = ""):
    if len(str) > max_length:
        return set()
    if state == "A":
        return (gen_strings(max_length, "B", str + "0") |
                gen_strings(max_length, "C", str + "1"))

    elif state == "B":
        return gen_strings(max_length, "D", str + "1")

    elif state == "C":
        return gen_strings(max_length, "D", str + "0")

    elif state == "D":
        return ({str} |
                gen_strings(max_length, "A", str + "0")
                gen_strings(max_length, "A", str + "1"))

要自上而下执行,只需按照resultstate传递的方式传递str

def gen_strings(max_length, state="A", str="", result=None):
    if len(str) > max_length:
        return
    if state == "A":
        gen_strings(max_length, "B", str + "0", result)
        gen_strings(max_length, "C", str + "1", result)
    # etc.

问题是这不会返回结果,它会将其作为参数 - 您必须在顶层传递一个空集,如下所示:

result = set()
gen_strings(max_length, result=result)

但你可以随时把它包起来。将gen_strings重命名为gen_strings_r,然后写下:

def gen_strings(max_length, state="A", str=""):
    result = set()
    gen_strings_r(max_length, state, str, result)
    return result

或者你可以将两者结合起来,传递一个值来用来构建一个返回向上的值。这为您提供了自下而上(避免变异)和自上而下(允许尾调用)的好处,这使其成为函数式语言中非常常见的习惯用语,尤其是纯函数式语言。但在这种情况下,它没有优于纯粹自下而上的优势,它需要对代码进行更大的更改,因此我不会费心去编写它。

答案 1 :(得分:0)

您可以使用闭包:

def gen_str(max_length, state = "A", str = ""):
    result  = set()    

    def rec_gen_strings(max_length, state = "A", str = ""):

        if len(str) > max_length:
            return
        if state == "A":
            rec_gen_strings(max_length, "B", str + "0")
            rec_gen_strings(max_length, "C", str + "1")

        elif state == "B":
            rec_gen_strings(max_length, "D", str + "1")

        elif state == "C":
            rec_gen_strings(max_length, "D", str + "0")

        elif state == "D":
            result.add(str)
            rec_gen_strings(max_length, "A", str + "0")
            rec_gen_strings(max_length, "A", str + "1")

    rec_gen_strings(max_length, state, str)
    return result