CS61a中div_by_primes_under内checker函数的实现与原理疑问
关于div_by_primes_under函数的疑问解答
疑问1:是否checker会因"i%i==0"总是返回True?
不会。关键在于两个细节:
- 只有当
not checker(i)为真时才会更新checker,而checker(i)为假说明当前的i不能被之前找到的任何质数整除——换句话说,i本身是质数。如果i是合数,它必然能被小于它的某个质数整除,此时checker(i)会返回True,不会触发更新逻辑。 - 更新后的checker检查的是输入值
x%i ==0,而非i%i==0。这里的i是当前循环中确定的质数,后续调用检查器时,传入的是待判断的k,和此时的i没有关系。
疑问2:checker函数的工作机制是什么?
checker是一个逐步构建的链式检查函数:
- 初始状态下,checker是一个永远返回False的函数(
lambda x: False),表示还没有任何质数需要检查。 - 从i=2遍历到n:
- 若i是质数(
not checker(i)为真),就生成新的checker函数。这个新函数会先判断输入的x是否能被当前质数i整除,能的话直接返回True;不能则调用之前的checker,检查x是否能被更早找到的质数整除。 - 若i是合数,直接跳过更新,继续下一个数。
- 若i是质数(
- 最终返回的checker会依次检查所有≤n的质数,只要x能被其中任意一个整除就返回True,否则返回False。
疑问3:该lambda函数的核心逻辑是什么?
核心是用闭包实现函数链式组合,同时规避循环变量的作用域问题:
(lambda f, i: lambda x: x % i == 0 or f(x))(checker, i)这段代码,本质是把旧的检查逻辑(checker)和当前的质数i绑定,生成新的检查函数。- 外层lambda接收旧checker(f)和当前质数(i),返回的内层lambda会保留这两个值的引用。这样后续循环中i的值改变时,已经生成的内层lambda不会受影响,依然使用当时绑定的质数i。
- 每次组合都是在原有检查逻辑基础上,新增一个“是否能被当前质数整除”的判断,最终形成覆盖所有≤n质数的检查链。
内容的提问来源于stack exchange,提问作者xucheng Zhu
相关产品推荐
相关产品推荐

