编程问题与算法解析合集

44、定义一个谓词 equal-after-transfer?,它接收两个自然数。如果这两个数相等,则返回 #t;如果第一个参数为 0 且第二个参数为正数,则返回 #f。假设有一个 transfer-unit 过程,它接收一个自然数作为参数并返回一个新的自然数。如果上述两个条件都不满足,该谓词应将 transfer-unit 过程应用于这些参数,并对结果重复此过程。因此,equal-after-transfer? 将确定在第一个数减为 0 之前,从第一个给定的数向第二个数进行任意次数的单位转移是否会使结果相等。

由于没有 transfer-unit 过程的具体定义,无法给出完整代码。但实现思路如下:

定义 equal-after-transfer? 函数,在函数内部判断两个数是否相等,若相等返回 #t ;判断第一个数是否为 0 且第二个数为正数,若是返回 #f ;若都不满足,使用 transfer-unit 函数处理参数并递归调用 equal-after-transfer?

示例代码框架如下:

(define (equal-after-transfer? num1 num2)
  (cond 
    ((= num1 num2) #t)
    ((and (= num1 0) (positive? num2)) #f)
    (else (equal-after-transfer? (transfer-unit num1) (transfer-unit num2)))))

需根据 transfer-unit 实际定义完善代码。

45、不使用计算机,用欧几里得算法计算 1152 和 1280 的最大公约数。

本题可根据欧几里得算法的原理,通过不断用较大数除以较小数取余数,将问题转化为求较小数和余数的最大公约数,直到余数为 0,此时的除数就是最大公约数。步骤如下:

  1. 因为 1280>1152,用 1280 除以 1152,得到商为 1,余数为 1280 - 1152×1 = 128。
  2. 此时问题转化为求 1152 和 128 的最大公约数。用 1152 除以 128,得到商为 9,余数为 1152 - 128×9 = 0。
  3. 当余数为 0 时,除数 128 就是 1152 和 128 的最大公约数,也就是 1152 和 1280 的最大公约数。

所以,1152 和 1280 的最大公约数是 128。

46、证明在我们实现的欧几里得算法中,预处理适配器是多余的,即使用更简单的定义 (define greatest - common - divisor (pipe (iterate divisible - by? (dispatch >next mod)) >next)) 总能得到相同的结果。(提示:如果我们不遵守迭代器的第一个参数大于或等于第二个参数的前提条件,当较小的数除以较大的数时,第一次除法会发生什么?)

当不遵守迭代器的第一个参数大于或等于第二个参数的前提条件,让较小数除以较大数时,余数就是较小的数本身。在后续迭代中,就相当于交换了两数的顺序,继续执行算法。

所以即便不使用预处理适配器调整参数顺序,最终也能得到相同的最大公约数结果,即预处理适配器是多余的。

47、定义一个一元谓词,它可以接收任意整数,并判断该整数是否能被 2、3 和 5 整除,但不能被 7 整除。(例如,2490 满足这个谓词,但 2510 和 2520 不满足。)

以下是实现该功能的代码示例(以 Scheme 语言为例):

(define (divisible-by-2-3-5-not-7? num)
  (and (zero? (modulo num 2))
       (zero? (modulo num 3))
       (zero? (modulo num 5))
       (not (zero? (modulo num 7)))))

该代码定义了一个名为 divisible-by-2-3-5-not-7? 的一元谓词,它接收一个整数作为参数,通过 and not 逻辑运算符结合取模运算来判断是否满足能被 2、3、5 整除但不能被 7 整除的条件。

48、在编程中,有如下代码定义:(define (iterate final? step) (rec iterator (^if final? values (pipe step iterator))))。然而,这个定义在实际调用 iterate 时会失败,产生如“# 不是一个过程”这样的隐晦错误信息。这个定义有什么问题?(提示:思考 rec 表达式在什么条件下可以建立递归局部绑定,以及该绑定何时可用。)

问题出在 rec 表达式建立递归局部绑定的时机上。在

(rec iterator (^if final? values (pipe step iterator)))

里,当使用 ^if 时, (pipe step iterator)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值