如果输入字符串满足非确定性有限状态机/自动机,我编写了测试输入字符串的代码。逻辑对我来说似乎很好,但由于stackoverflow代码崩溃,因为递归函数没有返回。
原因是字典总是为输入返回相同的结果,即使对于相同的输入字典有两个不同的输出。
def hello(curExist, curTemp, string, dict, accept):
print "curExist: ", curExist, " curTemp: ", curTemp, " Letter: ", string;
if(string == ""):
return curExist in accept;
elif((curTemp,string[0]) in dict):
curExist = curTemp = dict[(curTemp,string[0])];
return hello(curExist, curTemp, string[1:], dict, accept);
elif((curTemp,'') in dict):
curTemp = dict[(curTemp, '')];
return hello(curExist, curTemp, string, dict, accept);
elif((curExist, '') in dict):
curTemp = dict[(curExist, '')];
return hello(curExist, curTemp, string, dict, accept);
else:
return False;
dict={(1,'a'):2, (2,''):6, (6,''):4, (2,''):3, (3,'b'):4, (4,'c'):5};
mString = "ac";
accept=[5];
print hello(1,1,mString,dict,accept);
控制台输出:
curExist: 1 curTemp: 1 Letter: ac
curExist: 2 curTemp: 2 Letter: c
curExist: 2 curTemp: 3 Letter: c
curExist: 2 curTemp: 3 Letter: c
curExist: 2 curTemp: 3 Letter: c // printing this untill crash
.
.
.
我该如何解决这个问题?
答案 0 :(得分:2)
Keys in dictionaries need to be unique and immutable(因为它们是经过哈希处理的),您不能拥有2个相同的键:
>>> foo = { (2, ''): "bar", (2, ''): "zulu" }
>>> foo
{(2, ''): 'zulu'}
另外:
dict
。它是字典的构造函数答案 1 :(得分:0)
@IanClark是对的,键必须是唯一的。一个简单的解决方案是将您的字典签名转换为pair -> list
。该签名自然地捕获非确定性自动机,(当前状态,符号) - > (可能的下一个国家名单)。所以,你的例子dict变成了
dictionary={(1,'a'):[2], (2,''):[6, 3], (6,''):[4], (3,'b'):[4], (4,'c'):[5]};
最后,在您的elif
分支中,循环遍历字典条目中的所有元素,并递归调用hello
。类似的东西:
elif((curTemp,'') in dict):
curTempList = dictionary[(curTemp, '')];
tempBool = False
for newCurrTemp in currTempList:
tempBool = tempBool or hello(curExist, curTemp, string, dictionary, accept);
return tempBool
您的递归调用会返回True
或False
。如果这些调用中至少有一个是True
,则接受该字符串。因此or
声明为tempBool
。
这种方法可能仍然会造成浪费的递归调用(想想使用相同的输入调用hello
但是来自if
的不同分支。更好的解决方案是记忆,例如,这个:What is memoization and how can I use it in Python?