首页 > 解决方案 > 使用两个检查遍历两个列表

问题描述

一个函数接受三个参数:

  1. 与笔记本电脑成本有关的数字列表
  2. 表示笔记本电脑是否有缺陷的字符串列表,即“合法”或“非法”
  3. 一个整数,表示一天内要生产的笔记本电脑的数量。

因此,如果输入类似于:

cost = [1,3,2,5,4,1]
labels = ['legal', 'illegal', 'legal', 'legal', 'legal', 'legal']
dailyCount = 2

输出必须是总最大成本,因此第一天的成本=(1 + 3 + 2)即6。我们也计算非法物品的成本。第二天获得接下来的两个条目,因此成本 = (5+4) 即 9。下一个条目(最后剩余的)不足以计算每日计数,因此我们将其保留。因此,产生的总最大成本为 6+9 = 15。函数返回。这是我在几个小时后得到的结果:

    def maxCost(cost, labels, dailyCount):
        count = 0 #counts the number of legal laptops made
        money = 0 #counts daily cost incurred
    
        def calc(labels, count, money):
            if len(labels) > 0:
                for i in range(len(labels)):
                    money += cost[i]
                    if labels[i] == 'legal':
                        count += 1
                    if count == dailyCount:
                        calc(labels[i:], 0, money)
            return money
        
        res = calc(labels,count,money)
        return res
cost = [1,2,4,3]
labels = ['legal','illegal','legal','legal']
dailyCount = 2
print(maxCost(cost, labels, dailyCount))

输出应该是 5。但它显示 10 我不知道怎么做?

标签: python-3.x

解决方案


问题:

  • 递归调用(如果会进行)返回一个金额,但您忽略该值,因为您没有将它分配给任何东西。

  • 您的代码似乎暗示您认为参数(有时)是对调用者变量的引用,并且更改 - 比如说 -money会影响外部money变量,但事实并非如此。所有参数都传递给局部变量,并且对这些变量的任何赋值都不会反​​映在作为参数传递的变量中。

  • count每次达到一整天的价值时,都应将其重置为 0。所以count可以是calc函数的局部变量。它不应该在其他地方定义,也不应该作为参数传递(无论如何你总是传递 0,所以这不是很有用)。

  • 目前money不累积在不同的日子。要累积,请使用返回值并将其添加到调用者的局部 money变量中。同样,它不需要money作为参数传递。让每个电话返回适用于其案件的钱,并让来电者将自己的一天价值添加到其中。

  • 没有检查您是否在最后一天获得了全部笔记本电脑。money如果没有,应该忽略已经累积的。所以最好在递归调用后立即返回。如果然后 for 循环在没有完成新的返回的情况下退出,那么我们知道生产的笔记本电脑的数量还不够,我们应该这样做return 0

  • 在递归调用中,你通过了[i:],但i已经被处理了,所以你应该 slice [i+1:]

  • 您的递归调用得到一个切片labels列表,但cost没有切片,因此索引不再i对齐,并且通过抓取cost[i]您不会获得与切片列表中的i索引相关的成本。因此,我建议您不要切片,而是通过索引 ( ) labelsii+1

  • 最后一个代码示例的正确输出也不应该是 5:它应该是 7,因为应该考虑到第二台笔记本电脑的“非法”成本。

用递归解决这个问题有点矫枉过正,但我​​会在这个版本中保留它:

def maxCost(cost, labels, dailyCount):
    def calc(start):
        count = 0
        money = 0
        if len(labels) > 0:
            for i in range(start, len(labels)):
                money += cost[i]
                if labels[i] == 'legal':
                    count += 1
                if count == dailyCount:
                    return money + calc(i+1)
        return 0 # not enough labels
    
    res = calc(0)
    return res

作为替代方案,这里有一个解决方案,首先计算合法笔记本电脑的数量,然后得出应该生产的数量(必须是每日数量的倍数),然后搜索最后一台合法笔记本电脑的索引,最后将成本相加到那台笔记本电脑:

def maxCost(cost, labels, dailyCount):
    numlegals = sum(1 for label in labels if label == 'legal')

    # truncate to a multiple of dailyCount
    numlegals -= numlegals % dailyCount
    for i, label in enumerate(labels):
        if label == 'legal':
            numlegals -= 1
            if numlegals == 0:
                return sum(cost[:i+1])

推荐阅读