Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用递归显示字符串中的多个子字符串索引_Python_Recursion - Fatal编程技术网

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
a
list
并不是一个很好的实践,因为每次
[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)]