我正在尝试编写类似于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))))
我似乎走在正确的轨道上 - (搜索列表'al alist)返回1.但是,当使用(search-list'b alist)进行测试时,这是我的输出:((b.2)( c.3))
我无法理解为什么我的程序不能按照我的意图运作。如果你能在我的程序中指出错误,我会很高兴。提前谢谢。
答案 0 :(得分: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)))))
答案 1 :(得分:0)
问题是最后一行的搜索列表中的呼叫(或缺少呼叫)。由于这没有包含在括号中,因此从不以递归方式调用过程,并返回过程(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)))))
答案 2 :(得分:0)
请注意,您不需要assq
的完全行为(assoc
使用eq?
而不是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)
。