8

我正在阅读“Little Schemer”一书,并执行各种功能。一般来说,我最终会得到与书籍相同的版本,但不是 eqlist?,这是一个测试两个列表是否相等的函数。

我试过测试我的版本,它通过了我扔给它的任何东西。然而,它与“Little Schemer”版本略有不同,我希望有人对我是否遗漏一些东西发表意见——我怀疑是这样。

我的版本:

(define eqlist?
  (lambda (list1 list2)
    (cond
      ((and (null? list1)(null? list2))#t)
      ((or (null? list1)(null? list2))#f)
      ((and (atom? list1)(atom? list2))(eqan? list1 list2))
      ((or (atom? list1)(atom? list2)) #f)
      (else
        (and(eqlist? (car list1) (car list2))
            (eqlist? (cdr list1) (cdr list2)))))))

书的版本:

(define eqlist2? ;This is Little Schemer's version
  (lambda (list1 list2)
    (cond
      ((and (null? list1)(null? list2)) #t)
      ((or (null? list1)(null? list2)) #f)
      ((and (atom? (car list1))(atom? (car list2)))
       (and (eqan? (car list1)(car list2))(eqlist2? (cdr list1)(cdr list2))))
      ((or (atom? (car list1))(atom? (car list2))) #f)
      (else
       (and (eqlist2? (car list1)(car list2))
            (eqlist2? (cdr list1)(cdr list2)))))))

在这两种情况下,eqan 的定义是:

(define eqan?
  (lambda (a1 a2)
    (cond
      ((and (number? a1)(number? a2)) (equal? a1 a2))
      ((or (number? a1)(number? a2)) #f)
      (else (eq? a1 a2)))))

谢谢!

乔斯·德拉格

4

2 回答 2

6

如果传入一个原子或不正确的列表(一对不是列表 - 类似于(1 2 . 3))作为参数,则书籍版本会中断。(请注意,它'()当然可以eqv?equal?. eqlist?(我看到equal?用于eqan?测试数值相等性,但传统上这个名称附加到通用值相等性测试函数。)

基本上,您eqlist?在以下假设下对任何类型的参数进行工作:(1)atom?能够区分非对(它是 的否定版本car),(2)测试原子的相等性,(3)一切要么是一对,要么是一个原子。(嗯,实际上在我眼中是一个原子——Petite Chez Scheme 同意。)本书版本适用于正确的列表(包括),做出类似的假设并忽略遇到不正确列表的可能性。cdrpair?eqan?'()'()'()

如果本书后面介绍了更强大的相等性测试功能,我不会感到惊讶,但我没有它可供检查。无论如何,eqlist?您发布的书籍版本似乎是为了说明列表背后的基本思想,而不是您真正想在日常编程中使用的东西。事实上,给定版本的eqan?将在不受限制的环境中中断,在该环境中需要考虑更多原子类型的数据,其中至少需要单独考虑字符串,从而使上面第二段中列出的假设无效并中断的两个版本eqlist?

于 2010-03-04T13:55:43.980 回答
1

这是我的版本:

(define eqlist?
    (lambda (l1 l2)
      (cond
        ((and (null? l1) (null? l2))
         #t)
        ((and (atom? (car l1)) (atom? (car l2)))
         (and (eq? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2))))
        (else
         (and (eqlist? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2)))))))
于 2017-07-11T13:24:43.440 回答