【问题标题】:How to use recursion with elements in the list?如何对列表中的元素使用递归?
【发布时间】:2012-11-24 12:30:05
【问题描述】:

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

(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

你知道我应该怎么做吗?

【问题讨论】:

    标签: list recursion lisp scheme compare


    【解决方案1】:

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

    • 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 存储列表的其余部分。在遍历的每个点,我们检查前一个元素和当前元素的谓词是否为假——如果是这样,那么我们返回假。如果不是,我们继续使用新的prev(当前元素)和列表的其余部分进行递归。我们一直这样下去,直到列表为空,然后我们才返回 true。

    【讨论】:

    • 我知道 apply 但我不能使用它。这就是问题所在。 :(
    • 我有点傻。这里应该是什么: (??> ; if pred? 对于prev 和当前元素为假。这里: (loop ??> ??>)))))) ;通过新的prev 和列表的其余部分。在 ??-> (loop (car list) (cdr list))) 或别的什么
    • @Ats:第二部分是正确的。对于第一部分:这是程序的核心,想一想:什么会使整个程序返回false?怎么样:前一个元素和当前元素与pred? 相比,评估为假。
    • 我已经尝试了一整天,但没有任何效果。我试过:(pre?(car lis)prev),(pre?prev(car lis))。我不知道我应该在那里写什么。
    • @Ats 你几乎明白了......好吧,我会帮你做最后的细节 - 我们返回 false 如果pred? 是 false。这就是我的意思:(not (pred? prev (car ls)))。我希望这能解决您的问题,如果对您有帮助,请不要忘记接受答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多