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)
当前输出错误:
[5, 22, 9, 19, 14]
我无法在前一个递归步骤中求和子字符串的长度。与列表中的第二个元素一样,29
应该是22
,而不是len(previousSubstring) + len(key) - 1 + len(currentSubstring)
中的{{1}}。
有任何想法可以改进我的代码和/或修复我的错误吗?
答案 0 :(得分:5)
您不必实施自己的解决方案,它已经完成了!使用finditer
模块中的re
功能:
>>> 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]
如果你想自己实现(使用递归),你可以利用str.find
函数的额外参数。让我们看看help(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.
还有一个名为start
的额外参数告诉str.find
从哪里开始搜索子字符串。这正是我们所需要的!
因此,修改您的实施,我们可以获得一个简单,快速和美观的解决方案:
def substring_match_exact(pattern, string, where_should_I_start=0):
# Save the result in a variable to avoid doing the same thing twice
pos = string.find(pattern, where_should_I_start)
if pos == -1:
# Not found!
return []
# No need for an else statement
return [pos] + substring_match_exact(pattern, string, pos + len(key))
[]
。[pos]
以及子字符串在位置pos + len(key)
的字符串开始中显示的所有位置。>>> s = 'your code works with wrongly correlated coefficients which incorporates more costs'
>>> substring_match_exact('co', s)
[5, 29, 40, 61, 77]
答案 1 :(得分:4)
目前,您的代码正在尝试在缩短的字符串中找到co
的索引,而不是原始字符串。因此,虽然[5, 22, 9, 19, 14]
可能看起来不正确,但脚本正在完全按照您的要求执行操作。通过包含偏移量,如下面的脚本,这段代码可以工作。
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)
我应该补充一点,在处理只有一个值时,从一开始就使foundStringAt
成为list
不是很好的做法,因为你在每个[0]
索引查找中添加了一些开销。相反,既然你想要一个list
返回类型,你应该把它放在return语句中的[]
中(如我的代码所示)。
答案 2 :(得分:2)
您总是在相应的子字符串中添加位置。在
return foundStringAt + subStringMatchExact(target, key)
,函数调用的结果与“new”字符串target
相关,后者与“旧”字符串不同,因为它是使用target = target[foundStringAt[0] + len(key):]
重新定义的。
所以你应该将这个值恰好添加到函数调用结果中:
foundStringAt = target.find(key)
offset = foundStringAt + len(key)
target = target[offset:]
return [foundStringAt] + [i + offset for i in subStringMatchExact(target, key)]
应该做的伎俩(未经测试)。
答案 3 :(得分:0)
除了作为练习外,我不打算使用递归。
解决问题:
我无法在前一个递归步骤中总结子字符串的长度。
您真正想要“求和”的是已搜索过的字符串数量。将此函数作为参数传递给函数(第一次调用使用0),将删除的字符串数量(当前为foundStringAt[0] + len(key):
)添加到递归调用的输入值中。
作为格式化(并使事物更好地与其名称相对应),您可能会发现让foundStringAt
直接存储结果(而不是那个1元素列表)更为合适,并且列表包装作为表达式的一部分,带有递归调用。