1

我需要从列表中获取一个数字并将其转换为一个数字,以便我可以将其作为参数传递。

我试图在方案中制作一个 1 位加法器。我已经为或门和异或门以及半加器编写了代码,现在我试图将它们全部组合成一个全加器。我不确定我是否以正确的方式去做。任何输入将不胜感激谢谢。

(define or-gate
 (lambda (a b)
  (if (= a 1)
    1
    (if (= b 1)
    1
    0))))
(define xor-gate
 (lambda (a b)
  (if (= a b)
    0
    1)))

(define ha
 (lambda (a b)
  (list (xor-gate a b)(and-gate a b))))

(define fa
 (lambda (a b cin)
  (or-gate (cdr(ha cin (car (ha a b))))(cdr(ha a b)))))

我在运行程序时遇到的问题是半加法器 (ha) 函数将列表作为值输出,这使得这些值与我的其他程序不兼容,因为它们需要数字而不是列表。我觉得有一个简单的解决方案,但我不知道。

4

2 回答 2

2

如果你有合同,阅读你的代码会容易得多;我花了很长时间才推断出你的半加器正在返回一个位列表。

接下来,在我看来,您对“cdr”有一个简单的问题。“cdr”运算符不返回列表的第二个元素,而是返回列表的“其余部分”。查看 (cdr (list 1 1)) 和 1 之间的区别。第一个生成包含 1 的列表,第二个生成数字 1。

于 2012-04-06T06:56:41.267 回答
0

为避免混淆,最好使用过程firstsecond代替carcadr分别访问列表的第一个和第二个元素。请注意,cdr不会返回列表的第二个元素,而是返回列表的其余部分,即另一个列表。

无论如何,fa问题中的程序对我来说看起来不正确。它应该返回一个包含sumcout值的列表。这是实现它的一种可能方法,按照建议使用first和:second

(define fa
  (lambda (a b cin)
    (list (first (ha a (first (ha b cin))))
          (or-gate (second (ha a (first (ha b cin))))
                   (second (ha b cin))))))

...但这看起来令人困惑。请注意,我们(ha b cin)分三个部分进行计算,更好的做法是将重复计算保存在变量中,如下所示:

(define fa
  (lambda (a b cin)
    (let* ((partial1 (ha b cin))
           (partial2 (ha a (first partial1))))
      (list (first partial2)
            (or-gate (second partial2) (second partial1))))))

最后一点,在SICP书中,作为数字电路模拟器的一部分,加法器的实现非常好,请查看它以获取有关如何改进代码的更多想法。

于 2012-04-06T16:04:28.383 回答