我写了一个简短的程序,显示了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")
答案 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"))
要自上而下执行,只需按照result
和state
传递的方式传递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