如何使用列表中的元素递归?

时间:2012-11-24 12:30:06

标签: list recursion lisp scheme compare

我正在尝试在列表中使用递归,我需要遍历所有元素。这是我的代码:

(define compare
  (lambda (ls pred?)
    (if (null? list)
        #f
        (pred? (list-ref ls (- (length ls) 2)) (list-ref ls (- (length ls) 1))))))

但它仅适用于最后两个元素。结果应该是这样的:

(compare '(1 2 3 4 5) <) -> #t
(compare '(1 2 8 4 5) <) -> #f

你知道我应该做什么吗?

1 个答案:

答案 0 :(得分:3)

在代码中的任何地方使用递归。事实上,它有错误,我认为你没有彻底测试它。例如:

  • if条件应为(null? ls)
  • 在遍历Scheme中的列表时,不能使用list-ref,因为通常您希望使用递归,carcdr等。
  • 再次,递归调用在哪里?应该在某个时候调用compare

我相信这是你想要的,它不是递归的,但它是实现这个过程最简单的方法:

(define (compare ls pred?)
  (apply pred? ls))

因为这看起来像家庭作业,我只能给你一些从头开始解决问题的提示,而不使用apply。填写空白:

(define (compare ls pred?)
  (if <???>                    ; special case: if the list is empty
      <???>                    ; then return true
      (let loop ((prev <???>)  ; general case, take 1st element
                 (ls   <???>)) ; and take the rest of the list
        (cond (<???>           ; again: if the list is empty
               <???>)          ; then return true
              (<???>           ; if pred? is false for `prev` and current element
               <???>)          ; then return false
              (else            ; otherwise advance the recursion
               (loop <???> <???>)))))) ; pass the new `prev` and the rest of the list

请注意,我使用了一个名为let来实现递归,因此loop是递归过程:您可以看到looploop内被调用。或者,您可以定义一个帮助程序。考虑到列表最初为空的特殊情况,我必须这样做。

对于一般情况,递归的工作原理如下:需要两个参数,prev将前一个元素存储在列表中,ls存储列表的其余部分。在遍历中的每个点,我们检查谓词对于前一个和当前元素是否为假 - 如果是这种情况,那么我们返回false。如果没有,我们继续使用新的prev(当前元素)和列表的其余部分进行递归。我们继续这样做,直到列表为空,然后才返回true。