1

我正在尝试编写一个类似于 Scheme 的 assoc 的过程。两者之间的唯一区别是,我希望我的程序只返回与给定键相关的值,其中 assoc 给出整个对(键.值)。这是我的程序:

(define alist '((a . 1) (b . 2) (c . 3)))

(define (search-list key list)
  (cond ((null? key) #f)
        ((eq? (caar list) key) (cdar list))
        ((null? (cdr list)) #f)
        (else search-list key (cdr list))))

我似乎在正确的轨道上 - (search-list 'a alist) 返回 1。但是,当使用 (search-list 'b alist) 进行测试时,这是我的输出: ((b . 2) (c . 3 ))

我不明白为什么我的程序没有按我的意愿运行。如果您能指出我的程序中的错误,我将非常高兴。提前致谢。

4

3 回答 3

2

您发现了错误,但我建议进行其他更改:

1)您应该在使用之前检查列表是否为空等caar,因为当使用空列表调用您的程序时,您的程序将失败。

2)OTOH,无需检查键是否为空。

3)在Scheme中,您不应该将list其用作参数名称,以免影响过程list

所以我会去

(define (search-list key lst)
  (cond
    ((null? lst) #f)
    ((eq? key (caar lst)) (cdar lst))
    (else (search-list key (cdr lst)))))
于 2014-05-21T10:01:41.587 回答
0

问题是最后一行对 search-list的调用(或更确切地说是丢失的调用)。由于它没有被括在括号中,因此该过程从未被递归调用,并且该过程返回 (cdr list) 而不是 (search-list key (cdr list))。此代码按预期工作:

(define alist '((a . 1) (b . 2) (c . 3)))

(define (search-list key list)
  (cond ((null? key) #f)
        ((eq? (caar list) key) (cdar list))
        ((null? (cdr list)) #f)
        (else (search-list key (cdr list)))))
于 2014-05-21T09:46:58.803 回答
0

请注意,您并不完全希望assqassoc使用eq?not equal?)的行为,但您仍然可以assq在实现中使用:

(define (search-list key lst)
  (cond ((assq key lst) => cdr)
        (else #f)))

> (search-list 'b '((a . 1) (b . 2) (c . 3)))
2

此外,您现有的代码将无法列出'()因为caar将失败的列表。通常在递归算法中,首先测试基本情况,即(null? lst)您的情况。

于 2014-05-21T17:33:28.767 回答