我正在编写一个递归函数,它将采用两个字符串tbl2 <- tbl %>% filter(!is.numeric(col1))
和sub
。我必须找出string
是sub
的子字符串。
递归函数是一项严格的要求,无法删除。
这是我尝试过的,但它已经破了:
string
在以下情况下返回def is_substring(sub,string):
if sub=="":
return True
if string=="":
return False
if sub[0]==string[0]:
return is_substring(sub[1:],string[1:])
if sub[0]!=string[0]:
return is_substring(sub,string[1:])
而不是True
:
False
答案 0 :(得分:1)
你可以添加一个永远不会改变的函数参数:
def recur(completeString, string ) :
if string :
print string
recur(completeString, string[:-1])
else :
print "Nothing left from '{}'".format(completeString)
recur("hello", "hello")
这将输出:
hello
hell
hel
he
h
Nothing left from 'hello'
答案 1 :(得分:1)
保持递归函数的参数初始值的一种方法是使用附加的关键字参数。通常将此参数赋予默认值None
,因此函数的调用者不需要初始化此参数,但是当函数以递归方式调用自身时,它会在需要时进行适当设置。
例如:
def is_substring(sub, string, oldsub=None):
if sub == "":
return True
if string == "":
return False
if oldsub is None:
oldsub = sub
if sub[0] == string[0]:
return is_substring(sub[1:], string[1:], oldsub)
else:
return is_substring(oldsub, string[1:], oldsub)
保留值的另一种方法是通过在包装函数中定义递归函数来创建closure,如下所示:
def is_substring(sub, string):
oldsub = sub
def is_substringR(sub, string):
if sub == "":
return True
if string == "":
return False
if oldsub is None:
oldsub = sub
if sub[0] == string[0]:
return is_substringR(sub[1:], string[1:])
else:
return is_substringR(oldsub, string[1:])
return is_substringR(sub, string)
此函数实现与早期版本相同的算法。而且我很确定这是您尝试使用代码实现的算法。不幸的是,这种算法没有正确找到子串。
所以这里是 正常工作的递归is_substring
,但它不需要保留旧的参数值。
def is_substring(sub, string):
if sub == "":
return True
if string == "":
return False
if string.startswith(sub):
return True
else:
return is_substring(sub, string[1:])
# some tests
data = (
('misip', 'mississippi'),
('tle', 'cattle'),
)
for sub, target in data:
print('{!r} {!r} {}'.format(sub, target, is_substring(sub, target)))
<强>输出强>
'misip' 'mississippi' False
'tle' 'cattle' True
如果您不想使用.startswith
方法,则可以改为使用切片:
def is_substring(sub, string):
if sub == "":
return True
if string == "":
return False
if sub == string[:len(sub)]:
return True
else:
return is_substring(sub, string[1:])
正如我在评论中所说,进行子字符串测试的常用方法是使用in
运算符,该运算符调用字符串的.__contains__
方法。
sub in string
答案 2 :(得分:1)
问题是你的初始通话和后来的通话逻辑略有不同。如果失败,您的初始通话可以简单地前进到字符串中的下一个字符;您之后的电话必须从 sub 的开头重新开始。
我建议使用两个函数:一个包装函数,用于进行第一次比较并保留给定的接口(或者你可以更改它吗?),第二个函数将寻找到最后的连续匹配。
这是一个可能的解决方案,其中插入了跟踪打印语句(并已注释掉)。
def match_all(sub, string):
# print "ENTER ALL", sub, string
if sub == "":
# print "ALL empty sub; success"
return True
if string == "":
# print "ALL empty str; fail"
return False
if sub[0] == string[0]:
# print "ALL head match: recur"
return match_all(sub[1:],string[1:])
else:
# print "ALL head diff: fail"
return False
def is_substring(sub,string):
# print "ENTER TOP", sub, string
if sub == "":
# print "empty sub; success"
return True
if string == "":
# print "empty str; fail"
return False
if sub[0] == string[0]:
# print "head match: recur"
if match_all(sub[1:],string[1:]):
return True
# print "head diff: recur"
return is_substring(sub,string[1:])
print is_substring("misip", "mississippi")
# print "------------"
print is_substring("sip", "mississippi")
请注意逻辑更改:main函数查找立即结果,但如果找不到此类解析,仍会继续。支持函数仅查找此字符串位置的立即匹配。