递归函数接受方案中的列表

时间:2013-08-03 02:41:09

标签: scheme

我是Scheme的新手,这是我的第一本功能语言。递归地实现几乎所有东西对我来说似乎很尴尬。然而,能够实现具有单个整数输入的Factorial和Fibonacci问题的函数。

但是,当你的函数输入列表时呢?假设这个练习:

  

功能:ret10 - 提取并以列表形式返回所有大于10的数字   在给定列表中找到的,guile> (ret10'(x e(h n)1 23 12 o))   输出:(23 12)

我应该将(定义c(列表))作为我的函数的参数吗?或者还有其他方式吗?

请帮忙。谢谢!


这是我的衍生解决方案,基于先生ÓscarLópez的回答。希望这有助于其他人:

(define (ret10 lst)
    (cond
        ((null? lst) '())

        ((and (number? (car lst)) (> (car lst) 10))
            (cons (car lst)
            (ret10 (cdr lst))))

        (else (ret10 (cdr lst)))
    )
)

2 个答案:

答案 0 :(得分:4)

这种问题,您收到一个列表作为输入并返回另一个列表作为输出具有一个众所周知的解决方案模板。我首先建议您查看The Little SchemerHow to Design Programs,这两本书都会教您正确的方法来开始考虑解决方案。

首先,我将向您展示如何解决类似问题:复制列表,完全按照它来说。这将证明解决方案的一般结构:

(define (copy lst)
  (cond ((null? lst)                ; if the input list is empty
         '())                       ; then return the empty list
        (else                       ; otherwise create a new list
         (cons (car lst)            ; `cons` the first element
               (copy (cdr lst)))))) ; and advance recursion over rest of list

现在让我们看看上面的问题与你的问题有什么关系。显然,递归的基本情况将是相同的。不同的是,我们cons第一个元素与列表的其余部分如果它是一个数字(提示:使用number?过程)它大于10。如果条件不成立,我们只是推进递归,而不需要任何东西。这是一般的想法,填补空白:

(define (ret10 lst)
  (cond (<???> <???>)          ; base case: empty list
        (<???>                 ; if the condition holds
         (cons <???>           ; `cons` first element
               (ret10 <???>))) ; and advance recursion
        (else                  ; otherwise
         (ret10 <???>))))      ; simply advance recursion

不要忘记测试它:

(ret10 '(x e (h n) 1 23 12 o))
=> '(23 12)

作为最后一点:通常你会使用filter过程解决这个问题 - 这个过程将列表作为输入,并作为输出返回另一个列表,只包含满足给定谓词的元素。在您学习并了解如何“手动”编写解决方案之后,请查看filter并使用它编写解决方案,以便比较不同的方法。

答案 1 :(得分:0)

解决列表的第一个元素的问题以及列表其余部分的递归问题。确保您处理终止条件(列表为null?)并合并结果(consappend以下内容)

(define (extract pred? list)
  (if (null? list)
      '()
      (let ((head (car list))
            (rest (cdr list)))
        (cond ((pred? head) (cons head (extract pred? rest)))
              ((list? head) (append (extract pred? head)
                                    (extract pred? rest)))
              (else (extract pred? rest))))))

(define (ret10 list)
  (extract (lambda (x) (and (number? x) (> x 10))) list))

> (ret10 '(0 11 (12 2) 13 3))
(11 12 13)