用两次检查遍历两个列表



函数有三个参数:

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

如果输入是这样的

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

产出必须是总最大成本,因此第一天的成本=(1+3+2)即6。非法物品的成本我们也算在内。第二天获得接下来的两个条目,所以cost=(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,我不知道怎么回事?

问题:

  • 递归调用(如果要进行递归调用)返回一个货币金额,但您忽略该值,因为您没有将其赋值给任何东西。

  • 你的代码似乎暗示你认为参数(有时)引用调用者的变量,并且改变——让我们说——money将影响外部money变量,但这不是真的。所有参数都传递给局部变量,对这些变量的任何赋值都不会反映在作为参数传递的变量中。

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

  • 目前money不会在不同的日子累积。要累积,使用返回值并将其添加到调用方的本地money变量中。同样,不需要将money作为参数传递。

  • 没有检查你是否在最后一天达到了笔记本电脑的全部数量。如果没有,应该忽略已经积累的money。所以在递归调用之后立即返回是很好的。如果for循环退出而没有执行新的返回,那么我们知道生产的笔记本电脑的数量不够,我们应该执行return 0

  • 在递归调用中,你传递了[i:],但是i已经被处理了,所以你应该切片[i+1:]

  • 你的递归调用得到一个切片的labels列表,但是cost不是切片的,所以索引i不再很好地对齐,并且通过抓取cost[i],你没有得到与切片的labels列表中的i索引相关的成本。因此,我建议您传递i索引(i+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])

最新更新