【问题标题】:assoc-equivalent procedure not functioning properlyassoc 等效程序无法正常运行
【发布时间】:2014-05-21 09:20:52
【问题描述】:

我正在尝试编写一个类似于 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))

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

【问题讨论】:

    标签: scheme associative-array r5rs


    【解决方案1】:

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

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

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

    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)))))
    

    【讨论】:

      【解决方案2】:

      问题在于最后一行对 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)))))
      

      【讨论】:

        【解决方案3】:

        请注意,您并不完全希望 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)

        【讨论】:

          猜你喜欢
          • 2017-02-08
          • 2022-01-03
          • 2013-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-14
          • 2018-11-07
          相关资源
          最近更新 更多