简体   繁体   English

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

[英]recursive function accepts list in scheme

I'm new to Scheme and this is my very first Functional language. 我是Scheme的新手,这是我的第一个功能语言。 Implementing almost everything recursively seems to be awkward for me. 递归地实现几乎所有东西对我来说似乎很尴尬。 Nevertheless, was able to implement functions of Factorial and Fibonacci problems having a single integer input. 然而,能够实现具有单个整数输入的Factorial和Fibonacci问题的函数。

However, what about when your function has an input of a list? 但是,当您的函数输入列表时呢? Suppose this exercise: 假设这个练习:

FUNCTION: ret10 - extracts and returns as a list all the numbers greater than 10 that are found in a given list, guile> (ret10 '(xe (hn) 1 23 12 o)) OUTPUT: (23 12) 功能:ret10 - 提取并返回列表中给定列表中所有大于10的数字,guile> (ret10'(xe(hn)1 23 12 o))输出: (23 12)

Should I have (define c(list)) as the argument of my function in this? 我应该(定义c(列表))作为我的函数的参数吗? or is there any other way? 或者还有其他方法吗?

Please help. 请帮忙。 Thanks! 谢谢!


Here's my derived solution based on sir Óscar López's answer below.. hope this helps others: 这是我的衍生解决方案,基于先生Ó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)))
    )
)

This kind of problem where you receive a list as input and return another list as output has a well-known template for a solution. 这种问题,您收到列表作为输入并返回另一个列表作为输出有一个众所周知的解决方案模板。 I'd start by recommending you take a look at The Little Schemer or How to Design Programs , either book will teach you the correct way to start thinking about the solution. 我首先建议你看一下The Little Schemer如何设计程序 ,这两本书都会教你正确的方法来开始考虑解决方案。

First, I'll show you how to solve a similar problem: copying a list, exactly as it comes. 首先,我将向您展示如何解决类似的问题:复制列表,完全按照它来说。 That'll demonstrate the general structure of the solution: 这将展示解决方案的一般结构:

(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

Now let's see how the above relates to your problem. 现在让我们看看上面的问题与你的问题有什么关系。 Clearly, the base case for the recursion will be the same. 显然,递归的基本情况将是相同的。 What's different is that we cons the first element with the rest of the list only if it's a number (hint: use the number? procedure) and it's greater than 10 . 所不同的是,我们cons与列表的其余部分, 只有当它是一个数字的第一个元素(提示:使用number?的程序),它是大于10 If the condition doesn't hold, we just advance the recursion, without consing anything. 如果条件不成立,我们只是推进递归,而不需要任何东西。 Here's the general idea, fill-in the blanks: 这是一般的想法,填补空白:

(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

Don't forget to test it: 别忘了测试它:

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

As a final note: normally you'd solve this problem using the filter procedure - which takes as input a list and returns as output another list with only the elements that satisfy a given predicate. 最后要注意的是:通常你会使用filter程序来解决这个问题 - 它将输入作为一个列表并作为输出返回另一个列表,只包含满足给定谓词的元素。 After you learn and understand how to write a solution "by hand", take a look at filter and write the solution using it, just to compare different approaches. 在您学习并了解如何“手动”编写解决方案之后,请查看filter并使用它编写解决方案,以便比较不同的方法。

Solve the problem for the first element of the list and the recurse on rest of the list. 解决列表的第一个元素的问题以及列表其余部分的递归问题。 Make sure you handle the termination condition (list is null? ) and combine results ( cons or append in the following) 确保你处理终止条件(列表为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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM