社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

关于python递归的困惑

jayl151 • 6 年前 • 1199 次点击  

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

我写的代码如下:

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
 
1199 次点击  
文章 [ 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 以多个指向 物件 所有这些都是 相同的 精确列表,始终反映其当前状态,而不是添加到的状态 结果 . 在第二个程序中,您将传递 物件 所以所有的条目 结果 不同的 ,的状态 物件 当它被添加到 结果 .