Py学习  »  Python

关于python递归的困惑

jayl151 • 6 年前 • 1208 次点击  

我在写一个递归函数来解决一个问题,在这个问题中,你需要找到所有的组合,以达到给定数字的目标和,并且每个数字都小于某个限制。

我写的代码如下:

results = []

def findSchedulesHelper(workHours_left, dayHoursLimit, days_left, res):
    if workHours_left < 0:
        return
    elif workHours_left > 0 and days_left == 0:
        return
    elif workHours_left == 0 and days_left != 0:
        for i in range(days_left):
            res.append(0)
        results.append(res)
        return
    elif days_left == 0 and workHours_left == 0:
        results.append(res)
        return
    else:
        for i in range(dayHoursLimit + 1):
            res.append(i)
            findSchedulesHelper(workHours_left - i, dayHoursLimit, days_left - 1, res)
            res.pop()


def findSchedules(workHours, dayHours, pattern):
    # Write your code here
    num_question_mark = 0
    total_hours_so_far = 0
    for char in pattern:
        if char == "?":
            num_question_mark += 1
        else:
            total_hours_so_far += int(char)

    hours_left_to_fill = workHours - total_hours_so_far

    for i in range(dayHours + 1):
        findSchedulesHelper(hours_left_to_fill - i, dayHours, num_question_mark - 1, [i])
    print results

findSchedules(3,2,"??2??00")

但这给出了错误的答案。

如果我更改一行并使其成为:

results = []

def findSchedulesHelper(workHours_left, dayHoursLimit, days_left, res):
    if workHours_left < 0:
        return
    elif workHours_left > 0 and days_left == 0:
        return
    elif workHours_left == 0 and days_left != 0:
        for i in range(days_left):
            res.append(0)
        results.append(res)
        return
    elif days_left == 0 and workHours_left == 0:
        results.append(res)
        return
    else:
        for i in range(dayHoursLimit + 1):
            findSchedulesHelper(workHours_left - i, dayHoursLimit, days_left - 1, res + [i])


def findSchedules(workHours, dayHours, pattern):
    # Write your code here
    num_question_mark = 0
    total_hours_so_far = 0
    for char in pattern:
        if char == "?":
            num_question_mark += 1
        else:
            total_hours_so_far += int(char)

    hours_left_to_fill = workHours - total_hours_so_far

    for i in range(dayHours + 1):
        findSchedulesHelper(hours_left_to_fill - i, dayHours, num_question_mark - 1, [i])
    print results

findSchedules(3,2,"??2??00")

那么一切都是正确的。我真的很困惑为什么会这样。我试着做了一些调试,发现append和pop并不像我期望的那样工作。如果有人能解释我做这个函数的两种方法之间到底有什么区别,那就太好了。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38910
 
1208 次点击  
文章 [ 1 ]  |  最新文章 6 年前
cdlane
Reply   •   1 楼
cdlane    6 年前

第一个程序在 res ,递归调用 findSchedulesHelper() 调用后,删除添加的项:

res.append(i)
findSchedulesHelper(workHours_left - i, dayHoursLimit, days_left - 1, res)
res.pop()

而第二个程序通过一个新的列表 物件 加上额外的物品。在递归调用后不需要清理:

findSchedulesHelper(workHours_left - i, dayHoursLimit, days_left - 1, res + [i])

两者之间的一个区别是由于以下代码:

for i in range(days_left):
    res.append(0)

也就是说,递归调用 findscheduleshelper()。 有改变的潜力 物件 . 如果是这样的话, res.pop() 作为回报,你可能会移除一些你认为没有的东西。最后可能会有额外的数据 物件 下一个电话。第二个程序在传递 物件 再也不要查看或重复使用副本。

下一个潜在问题是多个调用:

results.append(res)

在第一个节目中,你通过了相同的 物件 列出,所以 results 以多个指向 物件 所有这些都是 相同的 精确列表,始终反映其当前状态,而不是添加到的状态 结果 . 在第二个程序中,您将传递 物件 所以所有的条目 结果 不同的 ,的状态 物件 当它被添加到 结果 .