Python 使用递归显示字符串中的多个子字符串索引
电流输出不正确:Python 使用递归显示字符串中的多个子字符串索引,python,recursion,Python,Recursion,电流输出不正确: def subStringMatchExact(target, key): if (target.find(key) == -1): return [] else: foundStringAt = [target.find(key)] target = target[foundStringAt[0] + len(key):] return foundStringAt + subStringMatc
def subStringMatchExact(target, key):
if (target.find(key) == -1):
return []
else:
foundStringAt = [target.find(key)]
target = target[foundStringAt[0] + len(key):]
return foundStringAt + subStringMatchExact(target, key)
string = subStringMatchExact("your code works with wrongly correlated coefficients which incorporates more costs", "co")
print(string)
在上一个递归步骤中,我对子字符串的长度求和有困难。与此类似,列表的第二个元素应该是29
,而不是22
,如len(previousSubstring)+len(key)-1+len(currentSubstring)
有什么想法可以改进我的代码和/或修复我的错误吗?快速方法
您不必实现自己的解决方案,它已经完成了!使用re
模块中的finditer
功能:
[5, 22, 9, 19, 14]
你自己的方式
如果您想自己实现(使用递归),可以利用str.find
函数的额外参数。让我们看看帮助(str.find)
对它的说明:
>>> import re
>>> s = 'your code works with wrongly correlated coefficients which incorporates more costs'
>>> matches = re.finditer('co', s)
>>> positions = [ match.start() for match in matches ]
>>> positions
[5, 29, 40, 61, 77]
另外还有一个名为start
的参数,它告诉str.find
从何处开始搜索子字符串。这正是我们需要的
因此,通过修改您的实现,我们可以得到一个简单、快速、美观的解决方案:
S.find(sub [,start [,end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within s[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
递归在这里做什么?
- 首先搜索从位置0开始的字符串中的子字符串
- 如果未找到子字符串,将返回一个空列表
[]
- 如果找到子字符串,它将返回
以及子字符串将出现在字符串中的所有位置,从[pos]
位置开始pos+len(键)
当前,您的代码正在尝试在缩短的字符串中查找
co
的索引,而不是原始的字符串。因此,虽然[5,22,9,19,14]
看起来可能不正确,但脚本正在执行您让它执行的操作。通过包含偏移量,如下面的脚本,此代码可以正常工作
>>> s = 'your code works with wrongly correlated coefficients which incorporates more costs'
>>> substring_match_exact('co', s)
[5, 29, 40, 61, 77]
我应该补充一点,当只处理一个值时,从一开始就创建
foundStringAt
alist
并不是一个很好的实践,因为每次[0]
索引查找都会增加一些开销。相反,因为您需要一个列表
返回类型,所以应该将它括在return语句的[]
中(如我的代码所示) 您总是在相应的子字符串中添加位置。在
def subStringMatchExact(target, key, offset=0): # note the addition of offset
if (target.find(key) == -1):
return []
else:
foundStringAt = target.find(key)
target = target[foundStringAt + len(key):]
foundStringAt += offset # added
return [foundStringAt] + subStringMatchExact(target, key, foundStringAt + len(key))
# added foundStringAt + len(key) part
string = subStringMatchExact("your code works with wrongly correlated coefficients which incorporates more costs", "co")
# no need to call w/ 0 since offset defaults to 0 if no offset is given
print(string)
,函数调用的结果与“新”字符串target
相关,该字符串不同于“旧”字符串,因为它是用target=target[foundStringAt[0]+len(key):]重新定义的
因此,您应该将此值添加到函数调用结果中:
return foundStringAt + subStringMatchExact(target, key)
应该可以做到这一点(未经测试)。除了作为练习之外,我不想为此使用递归
要解决此问题,请执行以下操作:
在上一个递归步骤中,我对子字符串的长度求和有困难
您真正想要“求和”的是已经搜索的字符串的数量。将其作为参数传递给函数(第一次调用使用0),将删除的字符串量(foundStringAt[0]+len(key):
,当前)添加到递归调用的输入值
关于格式(以及使事物更好地对应它们的名称),您可能会发现让foundStringAt
直接存储结果(而不是1元素列表)更整洁,并使用递归调用将列表包装为表达式的一部分。我想,通过print()
,这就是Python3,对吗?哦,正则表达式。我知道我知道如何有效地完成它,但我的代码中还有任何输入吗?我正在做麻省理工学院6.00开放式课程,刚刚阅读了关于递归的内容。这就是为什么我专注于通过递归来实现它。我知道这个话题背后的理论,但我想把这个“更难”的实际问题解决掉。阶乘和斐波那契太容易了,无法确保我正确理解这个概念。@cRaZiRiCaN:递归确实是一个非常有趣的概念。看看其他答案,充分了解您的解决方案的问题所在。每个基本编程问题都可以被视为家庭作业问题,因此我理解您不愿意提供“解决方案”(例如,仅提及补偿方法就足够了)。但非常感谢您对re模块的投入。我不知道。编辑:这是在我看到你的编辑之前,再次感谢。回答得好!只有一个小的打字错误matches=re.finditer('co')
应该是matches=re.finditer('co',s);)代码>“开销”不是问题;复杂性是。
return foundStringAt + subStringMatchExact(target, key)
foundStringAt = target.find(key)
offset = foundStringAt + len(key)
target = target[offset:]
return [foundStringAt] + [i + offset for i in subStringMatchExact(target, key)]