使用方案,我建立了二进制GCD算法(又称斯坦因算法)的迭代实现,以计算数字u
和v
的最大公共分母。此算法的步骤如下:
如果u和v均为奇数,且u≥v,则gcd(u,v)= gcd((u − v)/ 2,v)。如果两个都是奇数且u
重复步骤2-4,直到u = v,或重复一个步骤,直到u =0。在两种情况下,GCD均为2kv,其中k是在步骤2中找到的2的公因数。
我做的算法是这样的:
(define (stein u v)
(cond
((or (= u 0)(= u v))
v)
((and (even? u) (even? v))
(* 2 (stein (/ u 2)(/ v 2))))
((and (even? u) (odd? v))
(stein (/ u 2) v))
((and (odd? u) (even? v))
(stein u (/ v 2)))
((and (and (odd? u) (odd? v))(>= u v))
(stein (/ 2 (- u v)) v))
((and (and (odd? u)(odd? v))(< u v))
(stein (/ 2 (- v u)) u))))
我的问题是,每当遇到一个数字为奇数而另一个数字为偶数的情况时(输入就是这种方式,或者过程最终会以此方式调用自己),则输出要么为空,要么返回错误:Error: *: number required, but got #<undef> [stein, stein, stein, *]
有人可以解释为什么会发生这种情况以及如何解决吗?
谢谢!
答案 0 :(得分:5)
两行中有一个错误:
(stein (/ 2 (- u v)) v))
和
(stein (/ 2 (- v u)) u))))
您应将差值除以2,而不是相反。那就是:
(stein (/ (- u v) 2) v))
和
(stein (/ (- v u) 2) u))))
最后,请注意,需要进行测试以检查第二个参数是否等于0,否则在某些情况下该函数将永远循环。
类似这样的东西:
(define (stein u v)
(cond
((or (= u 0)(= u v))
v)
((= v 0) u)
((and (even? u) (even? v))
(* 2 (stein (/ u 2)(/ v 2))))
((and (even? u) (odd? v))
(stein (/ u 2) v))
((and (odd? u) (even? v))
(stein u (/ v 2)))
((and (and (odd? u) (odd? v))(>= u v))
(stein (/ (- u v) 2) v))
((and (and (odd? u)(odd? v))(< u v))
(stein (/ (- v u) 2) u))))