3

刚接触 Python 并试图理解递归。我正在尝试制作一个程序,该程序使用递归函数打印出在字符串“目标”中找到字符串“键”的次数,如 MIT 介绍课程问题集的问题 1 中所示。我在试图弄清楚该函数将如何运行时遇到问题。我已经阅读了文档和一些关于它的教程,但是有没有人有任何关于如何更好地理解递归来帮助我修复这段代码的提示?

from string import *

def countR(target,key):
    numb = 0
    if target.find(key) == -1:
        print numb
    else:
        numb +=1
        return countR(target[find(target,key):],key)

countR('ajdkhkfjsfkajslfajlfjsaiflaskfal','a')
4

4 回答 4

8

通过递归,您希望将问题拆分为较小的子问题,您可以独立解决这些子问题,然后将它们的解决方案组合在一起以获得最终解决方案。

在您的情况下,您可以将任务分为两部分:检查第一次出现的位置(如果)key,然后递归计算其余部分。

里面是否有键:
- 否:返回 0。
- 是:删除key并说键的数量是 1 +key其余的数量

在代码中:

def countR(target,key):
    if target.find(key) == -1:
        return 0
    else:
        return 1+ countR(target[target.find(key)+len(key):],key)

编辑
以下代码然后打印所需的结果:

print(countR('ajdkhkfjsfkajslfajlfjsaiflaskfal','a'))
于 2012-08-05T23:03:42.590 回答
1

这不是递归的工作方式。numb没用 - 每次您进入递归时,numb都会再次创建为 0,因此它只能是 0 或 1 - 绝不是您寻求的实际结果。

递归的工作原理是找到小问题的答案,然后用它来解决大问题。在这种情况下,您需要在不包含第一次出现的字符串中找到键的出现次数,并将其加 1。

此外,您需要实际推进切片,以便您刚刚找到的字符串不会再次出现。

from string import *

def countR(target,key):
    if target.find(key) == -1:
        return 0
    else:
        return 1+countR(target[target.find(key)+len(key):],key)

print(countR('ajdkhkfjsfkajslfajlfjsaiflaskfal','a'))
于 2012-08-05T23:07:11.413 回答
1

我见过的大多数递归函数都强调返回一个有趣的值,在此基础上构建更高的帧。你的函数没有这样做,这可能就是它让你感到困惑的原因。这是一个递归函数,可为您提供整数的阶乘:

def factorial(n):
    """return the factorial of any positive integer n"""
    if n > 1:
        return n * factorial(n - 1)
    else:
        return 1 # Cheating a little bit by ignoring illegal values of n

上面的函数演示了我称之为“正常”类型的递归——内部框架返回的值由外部框架操作。

您的功能有点不寻常,因为它:

  1. 并不总是返回一个值。
  2. 外框不会对内框的返回值做任何事情。

让我们看看我们是否可以重构它以遵循更传统的递归模式。(写成剧透语法,所以你可以看看你是否可以自己得到它,首先):

def countR(target,key): idx = target.find(key)` if idx > -1: return 1 + countR(target[idx + 1:], key) else: return 0

在这里,每次找到目标时countR添加,然后在字符串的其余部分上重复。1如果它没有找到匹配项,它仍然会返回一个值,但它会做两件关键的事情:

  1. 添加到外框时,不会更改值。
  2. 不再复发。

(好吧,所以关键的事情是它不做的事情。你明白了。)

元/编辑:尽管有这篇元文章,但显然不可能在剧透文本中正确格式化代码。所以我会保持它未格式化,直到该功能被修复,或者永远,以先到者为准。

于 2012-08-05T23:19:15.613 回答
0

如果在目标中找不到键,则打印 numb,否则创建一个新字符串,在找到的匹配项之后开始(因此剪掉开头)并从那里继续搜索。

于 2012-08-05T23:03:35.590 回答