Scheme自定义关联列表实现

时间:2015-11-10 18:02:24

标签: list scheme lisp

我正在尝试解决以下练习:

我必须实现一个函数make-empty-,它应该返回一个调度函数dispatch,它为以下结构的列表实现一些方法:((1a)(2b)(3a)(4c) )

调度功能应该有2个参数。 (只有缺点,并找到使用两者)。

方法应该是:

  • 空?如果列表是(),则应返回#t,否则返回#f
  • 汽车应该返回列表的第一个元素。例如(1 a)
  • cdr应返回没有第一个元素的列表。
  • 缺点应该在列表中添加一个元素
  • find应该返回与键匹配的值列表。

make-empty-应该从空列表的调度函数开始。

示例调用序列可以是:

(define a1 (make-empty-as))
(define a2 (a1 'cons '(b 2)))
(define a3 (a2 'cons '(d 4)))
(define a4 (a3 'cons '(c 5)))
(define a5 (a4 'cons '(a 6)))
(define a6 (a5 'cons '(c 4)))
(define a7 (a6 'cons '(b 7)))
(define a8 (a7 'cons '(a 1)))
(a8 'find 'b)
=>(7 2)
(a8 'find 'a)
=>(1 6)
(a7 'find 'a)
=>(6)
((a8 'cdr 'dummy) 'find 'a)
=>(6)

如您所见,缺点应该添加一个元素。添加一些元素后,元素应该是find。

我试图从缺点的实施开始,但不幸的是我被卡住了。我将传递的参数添加到(),但我不知道如何为下次调用保存此列表。

我目前的实施:

(define (make-empty-as)
    (define (dispatch arg1 arg2)
        (cond ((eq? arg1 'null?))
              ((eq? arg1 'car) '())
              ((eq? arg1 'cdr) '())
              ((eq? arg1 'cons) (cons arg2 ()) dispatch)
              ((eq? arg1 'find))
        )
    )
    dispatch
)

如果您想试用代码,可以在此处执行此操作:https://repl.it/BYpC

你能帮帮我吗?

此致

1 个答案:

答案 0 :(得分:2)

您的规格有点不寻常,但这会通过您的所有测试:

(define (make-as lst)
  (lambda args ; all arguments will be put in a list
    (let ((arg1 (car args))) ; first argument
      (cond
        ((eq? arg1 'null?) (null? lst))
        ((eq? arg1 'cons)  (make-as (cons (cadr args) lst))) ; create a new as with element prepended
        ((eq? arg1 'car)   (car lst))
        ((eq? arg1 'cdr)   (make-as (cdr lst))) ; create a new as with fir
        ((eq? arg1 'find)  (map cadr (filter (lambda (e) (eq? (car e) (cadr args))) lst)))))))

(define (make-empty-as)
  (make-as '()))

请注意,我在2个程序中拆分了问题;我可以用一个和一个可选的参数完成它,但是命名会很奇怪。

此外,无需给调度员一个名字(但你当然可以自己尝试一下)。

最后一个测试可以简化为((a8 'cdr) 'find 'a),不需要伪参数。

如果您熟悉case,可以将第一个程序修改为

(define (make-as lst)
  (lambda args ; all arguments will be put in a list
    (case (car args)
      ((null?) (null? lst))
      ((cons)  (make-as (cons (cadr args) lst))) ; create a new as with element prepended
      ((car)   (car lst))
      ((cdr)   (make-as (cdr lst))) ; create a new as with fir
      ((find)  (map cadr (filter (lambda (e) (eq? (car e) (cadr args))) lst))))))

这样做你想要的吗?