Skip to main content
 首页 » 编程设计

python之计算足球比赛中所有可能的得分方式(递归)

2025年05月04日20zhengyun_ustc

假设一个简化的足球计分系统,您可以得到 {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)))