假设一个简化的足球计分系统,您可以得到 {2, 3, 7} 分,给定一定数量的分数,您可以通过哪些方式得分?
我只是在做 EPI 书中的问题,他使用 DP 解决了这个问题。我想练习一种递归技术,但在尝试将所有不同的方法保存到结果列表中时遇到了麻烦。
def find_scoring(points, scores):
ways_to_score = [2, 3, 7]
def score_finder(p, scores):
print(scores, p)
if p == 0:
print('here')
results.append(scores)
return True
elif p <= 1:
return False
for i in ways_to_score:
scores.append(i)
if not score_finder(p-i, scores):
scores.pop()
return False
results = []
score_finder(points, scores)
return results
print(find_scoring(12, []))
对于以上内容,我希望看到 [[2,2,2,2,2,2], [2,2,2,3,3], ....]
我不知道如何正确传递分数变量。感谢协助!
请您参考如下方法:
results.append(scores)仅在我们需要副本时添加对scores的引用。我们可以用一个切片来做到这一点:scores[:]。- 不需要
if not score_finder(p-i, scores):;我们想要pop而不管我们是否在子节点中生成了成功的结果。 - 将临时
scores列表传递给score_finder函数对调用者来说有点负担。 - 相比之下,将
ways_to_score参数化以便调用者可以指定它是很好的,但使用默认参数则他们不必这样做。
这里有一个可能的重写,它解决了这些问题并稍微清理了逻辑:
def find_scoring(points, ways_to_score=[2, 3, 7]):
def score_finder(points, scores, result):
if points == 0:
result.append(scores[:])
elif points > 0:
for val in ways_to_score:
scores.append(val)
score_finder(points - val, scores, result)
scores.pop()
return result
return score_finder(points, [], [])
我们也可以返回一个生成器:
def find_scoring(points, ways_to_score=[2, 3, 7]):
def score_finder(points, scores, result):
if points == 0:
yield scores[:]
elif points > 0:
for val in ways_to_score:
scores.append(val)
yield from score_finder(points - val, scores, result)
scores.pop()
yield from score_finder(points, [], [])
if __name__ == "__main__":
print(list(find_scoring(12)))
